內(nèi)存管理篇: 5.ARC的規(guī)則補(bǔ)充
- ARC的方法命名
我們都知道躬窜,在內(nèi)存管理的思考方式中,當(dāng)方法命名以“alloc炕置、new荣挨、copy、mutableCopy”開(kāi)頭或直接命名時(shí)朴摊,返回對(duì)象(必須返回對(duì)象)的內(nèi)存由接收方進(jìn)行管理垦沉。這種方式在ARC中同樣適用。
在ARC環(huán)境下仍劈,以init或init開(kāi)頭的方法,也需要遵循此規(guī)則寡壮。且init的方法規(guī)定更為嚴(yán)格:
- 必須返回id或類型的對(duì)象
- 必須是實(shí)例方法
- OC對(duì)象(這里代指Foundation框架中類的對(duì)象)不能直接作為C數(shù)據(jù)結(jié)構(gòu)的成員贩疙。
原因:ARC為OC語(yǔ)言編譯器特性,不支持對(duì)C語(yǔ)言進(jìn)行內(nèi)存管理(最新的iOS 12中况既,好像已經(jīng)支持此特性了这溅,LLVM真強(qiáng)大。棒仍。悲靴。)
對(duì)于需要作為成員的OC對(duì)象,解決方法:
- 使用“__unsafe_unretained”進(jìn)行所有權(quán)修飾莫其,顯示聲明并告知編譯器不要對(duì)其進(jìn)行內(nèi)存管理癞尚;
- 通過(guò)“__bridge”將OC對(duì)象轉(zhuǎn)換為(void *)指針耸三。
- 顯示轉(zhuǎn)換“id”與“void *”
對(duì)象與C指針之間是通過(guò)“__bridge”關(guān)鍵字進(jìn)行轉(zhuǎn)換,主要分為三種方式:
- __bridge
- __bridge_retained
- __bridge_transfer
- __bridge:
直接轉(zhuǎn)換浇揩,忽略ARC內(nèi)存管理仪壮,與添加__unsafe_unretained效果類似:
id obj = [[NSObject alloc] init];
// 轉(zhuǎn)換為c指針
void *p = (__bridge void *)obj;
// 轉(zhuǎn)換為OC對(duì)象
id obj2 = (__bridge id)p;
- __bridge_retained:
意為“轉(zhuǎn)換后進(jìn)行保留”,接收方對(duì)其自動(dòng)強(qiáng)引用(同時(shí)掌握所有權(quán))胳徽,與__strong的retain效果類似:
void *p = 0;
{
id obj = [[NSObject alloc] init];
// 轉(zhuǎn)換為c指針
p = (__bridge_retained void *)obj;
}
// 出作用域后积锅,obj強(qiáng)引用消失
// 由于__bridge_retained,p同時(shí)也是強(qiáng)引用养盗,對(duì)象得以繼續(xù)生存
NSLog("%@", [(__bridge id)p class]);
- __bridge_transfer:
意為“轉(zhuǎn)換后釋放”缚陷,原創(chuàng)建方在轉(zhuǎn)換后自動(dòng)釋放自身引用,只由接收方進(jìn)行內(nèi)存管理(轉(zhuǎn)換了所有權(quán))往核,與release效果類似:
void *p = xxx;
id obj = (__bridge_transfer id)p;
// 轉(zhuǎn)換后相當(dāng)于p進(jìn)行了release操作箫爷,只有obj持有對(duì)象
OC(Foundation)對(duì)象與CF(Core Foundation)對(duì)象間的轉(zhuǎn)換:
- 由于二者基本是等效框架(只是實(shí)現(xiàn)語(yǔ)言不同),對(duì)象間的轉(zhuǎn)換無(wú)需消耗CPU資源铆铆,是“免費(fèi)橋接”(“toll-free bridge”)蝶缀。
- 一般轉(zhuǎn)換規(guī)則:
- OC -> CF,使用“__bridge_retained”或“CFBridgingRetain”
- CF -> OC薄货,使用“__bridge_transfer”或“CFBridgingRelease”(因?yàn)橐话戕D(zhuǎn)換為OC對(duì)象后翁都,ARC可以自動(dòng)介入,防止忘記使用CFRelease手動(dòng)釋放內(nèi)存)
總結(jié):盡量不要直接使用__bridge進(jìn)行轉(zhuǎn)換谅猾,使用時(shí)需再三考慮內(nèi)存管理情況柄慰。
- 使用__strong、__weak和__autoreleasing修飾的變量税娜,其初始值會(huì)自動(dòng)賦值為nil