iOS允許Objective-C 和 Core Foundation 對(duì)象之間可以輕松的轉(zhuǎn)換,拿 NSString 和 CFStringRef 來(lái)說(shuō),直接轉(zhuǎn)換豪無(wú)壓力:
CFStringRef aCFString = (CFStringRef)aNSString;
NSString *aNSString = (NSString *)aCFString;
ARC的誕生大大簡(jiǎn)化了我們針對(duì)內(nèi)存管理的開(kāi)發(fā)工作,但是只支持管理 Objective-C 對(duì)象, 不支持 Core Foundation 對(duì)象。Core Foundation 對(duì)象必須使用CFRetain和CFRelease來(lái)進(jìn)行內(nèi)存管理。那么當(dāng)使用Objective-C 和 Core Foundation 對(duì)象相互轉(zhuǎn)換的時(shí)候,必須讓編譯器知道,到底由誰(shuí)來(lái)負(fù)責(zé)釋放對(duì)象,是否交給ARC處理。只有正確的處理,才能避免內(nèi)存泄漏和double free導(dǎo)致程序崩潰。
根據(jù)不同需求,有3種轉(zhuǎn)換方式
__bridge ? ? ? ? ? ? ? ? (不改變對(duì)象所有權(quán))
__bridge_retained 或者 CFBridgingRetain() ? ? ? ? ? ? ? (解除 ARC 所有權(quán))
__bridge_transfer 或者 CFBridgingRelease() ? ? ? ? ? ? (給予 ARC 所有權(quán))
1. __bridge_retained 或者 CFBridgingRetain()
__bridge_retained 或者 CFBridgingRetain() ?將Objective-C對(duì)象轉(zhuǎn)換為Core Foundation對(duì)象,把對(duì)象所有權(quán)橋接給Core Foundation對(duì)象,同時(shí)剝奪ARC的管理權(quán),后續(xù)需要開(kāi)發(fā)者使用CFRelease或者相關(guān)方法手動(dòng)來(lái)釋放對(duì)象。
來(lái)看個(gè)例子:
- (void)viewDidLoad{
[super viewDidLoad];
NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
(void)aCFString;
//正確的做法應(yīng)該執(zhí)行CFRelease,沒(méi)有release會(huì)內(nèi)存泄露。
//CFRelease(aCFString);
}
CFBridgingRetain() ?是 __bridge_retained 的宏方法,下面兩行代碼等價(jià):
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);