第五章:內(nèi)存管理
第二十九條:理解引用計(jì)數(shù)
理解引用計(jì)數(shù)這個(gè)可以通過《Objective-C 高級(jí)編程》這本書中的例子來理解,比較直觀,大概如下:
alloc/new/copy/mutableCopy retain release dealloc等自動(dòng)釋放池: 可以看到在我們程序中入口文件main.m中main函數(shù)中就包裹了一層autoreleasepool
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([HSAppDelegate class]));
}
}
autoreleasepool可以延長(zhǎng)對(duì)象的生命期,使其在跨越方法調(diào)用邊界后依然可以存活一段時(shí)間,通常是在下一次“時(shí)間循環(huán)”(event loop)時(shí)釋放,不過也可能會(huì)執(zhí)行的早一點(diǎn)。
- 保留環(huán): 也稱retain cycle,就是循環(huán)引用。形成原因就是對(duì)象之間相互用強(qiáng)引用指向?qū)Ψ剑瑫?huì)使得全部都無法得以釋放。解決方案通常是使用弱引用(weak reference)
第三十條:以ARC簡(jiǎn)化引用計(jì)數(shù)
使用ARC,可以省略對(duì)于引用計(jì)數(shù)的操作,所以在ARC下調(diào)用對(duì)象的retain,release,autorelease,dealloc方法時(shí)系統(tǒng)會(huì)報(bào)錯(cuò)。
這里要注意CoreFoundation 對(duì)象不歸ARC管理,開發(fā)中如果有用到還是要誰創(chuàng)建誰釋放,適時(shí)調(diào)用CFRetain/CFRelease。
第三十一條:在delloc方法中只釋放引用并解除監(jiān)聽
不要在delloc方法中調(diào)用其他方法,尤其是需要異步執(zhí)行某些任務(wù)又要回調(diào)的方法,這樣的很危險(xiǎn)的行為,很可能異步執(zhí)行完回調(diào)的時(shí)候該對(duì)象已經(jīng)被銷毀了,這樣就沒得玩了,crash了。
在delloc方法里應(yīng)該制作一些釋放相關(guān)的事情,包括不限于一些KVO取消訂閱,remove 通知等。
第三十二條:編寫“異常安全代碼”時(shí)留意內(nèi)存管理問題
這條有點(diǎn)重復(fù),之前已經(jīng)說過了,OC中拋出異常的時(shí)候可能會(huì)引起內(nèi)存泄漏,注意一下使用的時(shí)機(jī),或者注意在@try捕獲異常中清理干凈。
第三十三條:以弱引用避免保留環(huán)
這條比較簡(jiǎn)單,內(nèi)容主旨就是標(biāo)題:以弱引用避免保留環(huán)(Retain Cycle)
第三十四條:以“@autoreleasepool”降低內(nèi)存峰值
在遍歷處理一些大數(shù)組或者大字典的時(shí)候,可以使用自動(dòng)釋放池來降低內(nèi)存峰值,例如:
NSArray *people = /*一個(gè)很大的數(shù)組*/
NSMutableArray *employeesArray = [NSMutableArray new];
for (NSStirng *name in people) {
@autoreleasepool {
MLEmployee *employee = [MLEmployee alloc] initWithName:name];
[employeesArray addObject:employee];
}
}
第三十五條:用“僵尸對(duì)象”調(diào)試內(nèi)存管理問題
如上圖,勾選這里可以開啟僵尸對(duì)象設(shè)置。開啟之后,系統(tǒng)在回收對(duì)象時(shí),不將其真正的回收,而是把它的isa指針指向特殊的僵尸類,變成僵尸對(duì)象。僵尸類能夠響應(yīng)所有的選擇子,響應(yīng)方式為:打印一條包含消息內(nèi)容以及其接收者的消息,然后終止應(yīng)用程序
第三十六條:不要使用retainCount
在蘋果引入ARC之后retainCount已經(jīng)正式廢棄,任何時(shí)候都不要調(diào)用這個(gè)retainCount方法來查看引用計(jì)數(shù)了,因?yàn)檫@個(gè)值實(shí)際上已經(jīng)沒有準(zhǔn)確性了。但是在MRC下還是可以正常使用