ARC只會管理OC對象,而Core Foundation(簡稱CF)中的對象是用C語言實現的,這就意味著,分配給CF對象的內存需要手動釋放,否則會造成內存泄漏。
單獨使用CF對象時,通常不會忘記手動釋放內存。然而,OC對象和CF對象之間是可以相互轉換的(通過橋接),這時候就很容易犯錯。蘋果提供了三種橋接轉換的方法:
1、__bridge
__bridge只做類型轉換,不會改變對象的所有權(這里說的所有權即誰來管理這個對象的內存)。
1)OC對象轉成CF對象,test的所有權還在aNSStr手中,由ARC負責釋放。
NSString *aNSStr = [[NSString alloc] initWithFormat:@"test"];
CFStringRef aCFStr = (__bridge CFStringRef)aNSStr;
2)CF對象轉成OC對象,test的所有權還在aCFStr手中,所以必須手動釋放aCFStr,否則會有內存泄漏。
CFStringRef aCFStr = CFStringCreateWithCString(NULL, "test", kCFStringEncodingUTF8);
NSString *aNSStr = (__bridge NSString *)aCFStr;
CFRelease(aCFStr); // 這里必須釋放CF對象
2、__bridge_transfer,等價于CFBridgingRelease()
__bridge_transfer除了類型轉換,還會把CF對象的所有權移交到OC對象。
CF對象轉成OC對象,test的所有權從aCFStr移交到aNSStr手上,由ARC負責釋放。
CFStringRef aCFStr = CFStringCreateWithCString(NULL, "test", kCFStringEncodingUTF8);
1)NSString *aNSStr = (__bridge_transfer NSString *)aCFStr;
2)NSString *aNSStr = (NSString *)CFBridgingRelease(aCFStr);
3、__bridge_retained,等價于CFBridgingRetain()
__bridge_retained除了類型轉換,還會把OC對象的所有權搶過來給CF對象。
OC對象轉成CF對象,aCFStr把test的所有權從aNSStr手里搶過來,所以必須手動釋放aCFStr,否則會有內存泄漏。
NSString *aNSStr = [[NSString alloc] initWithFormat:@"test"];
1)CFStringRef aCFStr = (__bridge_retained CFStringRef) aNSStr;
2)CFStringRef aCFStr = (CFStringRef)CFBridgingRetain(aNSStr);
CFRelease(aCFStr); // 這里必須釋放CF對象