《編寫高質(zhì)量iOS與OS X代碼的52個有效方法》--第五章 第31條
(ps:此乃讀書筆記,加深記憶檐蚜,僅供大家參考)
第31條 在dealloc方法中只釋放引用并解除監(jiān)聽
對象在經(jīng)歷其生命周期后魄懂,最終會為系統(tǒng)回收,這時就要執(zhí)行dealloc方法了闯第。在每個對象的生命期內(nèi)市栗,此方法僅執(zhí)行一次,也就會說當(dāng)保留計數(shù)降為0的時候咳短。然而具體何時調(diào)用填帽,則無法保證。你絕不應(yīng)該自己調(diào)用dealloc方法咙好。運行期系統(tǒng)會在適當(dāng)?shù)臅r候調(diào)用它盲赊。
那么應(yīng)該在dealloc方法中做些什么呢?主要就是釋放對象所擁有的引用敷扫,也就是把所有Objective-C對象都是放掉哀蘑,ARC會通過自動生成.cxx_destruce方法在dealloc中為你自動添加這些釋放代碼。對象所擁有的其他非Objective-C對象也要釋放葵第。
在dealloc方法中绘迁,通常還要做一件事,那就是把原來配置過的觀測行為(observation behavior)都清理掉卒密。如果用NSNotificationCenter給此對象訂閱(register)過某種通知缀台,那么一般應(yīng)該在這里注銷(unregister),這樣的話哮奇,通知系統(tǒng)就不再把通知發(fā)給回收后的對象了膛腐。
雖說應(yīng)該于dealloc中釋放引用,但是開銷大或系統(tǒng)內(nèi)稀缺的資源則不在此列鼎俘。像是文件描述(file description)哲身、套接字(socket)、大塊內(nèi)存等贸伐,都屬于這種資源勘天。不能指望dealloc方法必定會在某個特定的時機調(diào)用,因為有一些無法預(yù)料的東西可能也持有此對象。如果非要等到系統(tǒng)調(diào)用dealloc方法時才釋放脯丝,那么保留這些稀缺資源的時間就有些過長了商膊,這么做不合適。通常的做法是宠进,實現(xiàn)另外一個方法晕拆,當(dāng)應(yīng)用程序用完資源對象后,材蹬,就調(diào)用此方法潦匈。這樣一來,資源對象的生命期就變得更為明確了赚导。
在清理方法而非dealloc方法中清理資源還有個原因,就是系統(tǒng)并不保證每個創(chuàng)建出來的對象的dealloc都會執(zhí)行赤惊。極個別情況下吼旧,當(dāng)應(yīng)用程序終止時,仍有對象處于存活狀態(tài)未舟,這些對象沒有收到dealloc消息圈暗。在Mac OS X及iOS應(yīng)用程序所對應(yīng)的application delegate中,都含有一個會于程序終止時調(diào)用的方法裕膀。如果一定要清理某些對象员串,那么可在此方法中調(diào)用那些對象的“清理方法”。
Mac OS X系統(tǒng)里昼扛,應(yīng)用程序終止時會調(diào)用NSApplicationDelegate之中的下列方法:
- (void)applicationWillTerminate:(NSNotification *)notification
而在iOS系統(tǒng)里寸齐,應(yīng)用程序終止時則會調(diào)用UIApplicationDelegate中的下述方法:
- (void)applicationWillTerminate:(UIApplication *)application
編寫dealloc方法時還需注意,不要在里面隨便調(diào)用其他方法抄谐。如果在這里調(diào)用的方法又要異步執(zhí)行某些任務(wù)渺鹦,或是又要繼續(xù)調(diào)用他們自己的某些方法,那么等到那些任務(wù)執(zhí)行完畢時蛹含,系統(tǒng)已經(jīng)把當(dāng)前這個待回收的對象徹底摧毀了毅厚。
請再注意一個問題:調(diào)用dealloc方法的那個線程會執(zhí)行“最終的釋放操作”(final release),令對象的保留計數(shù)降為0浦箱,而某些方法必須在特性的線程里(比如主線程)調(diào)用才行吸耿。若在dealloc里調(diào)用了那些方法,則無法保證當(dāng)前這個線程就是那些方法所需要的線程酷窥。
在dealloc里也不要調(diào)用屬性的存取方法咽安,因為有人可能會覆寫這些方法,并于其中做一些無法在回首階段安全之行的操作蓬推。此外板乙,屬性可能正處于“鍵值觀測”(Key-Value Observation, KVO)機制的監(jiān)控之下,該屬性的觀察者(observer)可能會在屬性值改變時“保留”或使用這個即將回收的對象募逞。
要點
- 在dealloc方法里蛋铆,應(yīng)該做的事情就是釋放指向其他對象的引用,并取消原來訂閱的“鍵值觀測”(KVO)或NSNotificationCenter等通知放接,不要做其他事情刺啦。
- 如果對象持有文件描述符等系統(tǒng)資源,那么應(yīng)該專門寫一個方法來釋放此種資源纠脾。這樣的類要和其使用者約定:用完資源后必須調(diào)用close方法玛瘸。
- 執(zhí)行異步任務(wù)的方法不應(yīng)該在dealloc里調(diào)用;只能在正常狀態(tài)下執(zhí)行的那些方法也不應(yīng)在dealloc里調(diào)用苟蹈,因為此時對象已處于正在回收的狀態(tài)了糊渊。