對(duì)象在經(jīng)歷其生命周期后皆尔,最終會(huì)為系統(tǒng)回收,這時(shí)就要執(zhí)行dealloc方法了币励。在每個(gè)對(duì)象的生命期內(nèi)慷蠕,此方法僅執(zhí)行一次,也就會(huì)說(shuō)當(dāng)保留計(jì)數(shù)降為0的時(shí)候食呻。然而具體何時(shí)調(diào)用流炕,則無(wú)法保證。你絕不應(yīng)該自己調(diào)用dealloc方法仅胞。運(yùn)行期系統(tǒng)會(huì)在適當(dāng)?shù)臅r(shí)候調(diào)用它每辟。
那么應(yīng)該在dealloc方法中做些什么呢?主要就是釋放對(duì)象所擁有的引用干旧,也就是把所有Objective-C對(duì)象都是放掉影兽,ARC會(huì)通過(guò)自動(dòng)生成.cxx_destruce方法在dealloc中為你自動(dòng)添加這些釋放代碼。對(duì)象所擁有的其他非Objective-C對(duì)象也要釋放莱革。
在dealloc方法中峻堰,通常還要做一件事,那就是爸原來(lái)配置過(guò)的觀測(cè)行為(observation behavior)都清理掉盅视。如果用NSNotificationCenter給此對(duì)象訂閱(register)過(guò)某種通知捐名,那么一般應(yīng)該在這里注銷(xiāo)(unregister),這樣的話闹击,通知系統(tǒng)就不再把通知發(fā)給回收后的對(duì)象了镶蹋。
雖說(shuō)應(yīng)該于dealloc中釋放引用,但是開(kāi)銷(xiāo)大或系統(tǒng)內(nèi)稀缺的資源則不在此列赏半。像是文件描述(file description)贺归、套接字(socket)、大塊內(nèi)存等断箫,都屬于這種資源拂酣。不能指望dealloc方法必定會(huì)在某個(gè)特定的時(shí)機(jī)調(diào)用,因?yàn)橛幸恍o(wú)法預(yù)料的東西可能也持有此對(duì)象仲义。如果非要等到系統(tǒng)調(diào)用dealloc方法時(shí)才釋放婶熬,那么保留這些稀缺資源的時(shí)間就有些過(guò)長(zhǎng)了剑勾,這么做不合適。通常的做法是赵颅,實(shí)現(xiàn)另外一個(gè)方法虽另,當(dāng)應(yīng)用程序用完資源對(duì)象后,饺谬,就調(diào)用此方法捂刺。這樣一來(lái),資源對(duì)象的生命期就變得更為明確了募寨。
在清理方法而非dealloc方法中清理資源還有個(gè)原因叠萍,就是系統(tǒng)并不保證每個(gè)創(chuàng)建出來(lái)的對(duì)象的dealloc都會(huì)執(zhí)行。極個(gè)別情況下绪商,當(dāng)應(yīng)用程序終止時(shí)苛谷,仍有對(duì)象處于存活狀態(tài),這些對(duì)象沒(méi)有收到dealloc消息格郁。在Mac OS X及iOS應(yīng)用程序所對(duì)應(yīng)的application delegate中腹殿,都含有一個(gè)會(huì)于程序終止時(shí)調(diào)用的方法。如果一定要清理某些對(duì)象例书,那么可在此方法中調(diào)用那些對(duì)象的“清理方法”锣尉。
Mac OS X系統(tǒng)里,應(yīng)用程序終止時(shí)會(huì)調(diào)用NSApplicationDelegate之中的下列方法:
- (void)applicationWillTerminate:(NSNotification *)notification
而在iOS系統(tǒng)里决采,應(yīng)用程序終止時(shí)則會(huì)調(diào)用UIApplicationDelegate中的下述方法:
- (void)applicationWillTerminate:(UIApplication *)application
編寫(xiě)dealloc方法時(shí)還需注意自沧,不要在里面隨便調(diào)用其他方法。如果在這里調(diào)用的方法又要異步執(zhí)行某些任務(wù)树瞭,或是又要繼續(xù)調(diào)用他們自己的某些方法拇厢,那么等到那些任務(wù)執(zhí)行完畢時(shí),系統(tǒng)已經(jīng)把當(dāng)前這個(gè)待回收的對(duì)象徹底摧毀了晒喷。
請(qǐng)?jiān)僮⒁庖粋€(gè)問(wèn)題:調(diào)用dealloc方法的那個(gè)線程會(huì)執(zhí)行“最終的釋放操作”(final release)孝偎,令對(duì)象的保留計(jì)數(shù)降為0,而某些方法必須在特性的線程里(比如主線程)調(diào)用才行凉敲。若在dealloc里調(diào)用了那些方法衣盾,則無(wú)法保證當(dāng)前這個(gè)線程就是那些方法所需要的線程。
在dealloc里也不要調(diào)用屬性的存取方法爷抓,因?yàn)橛腥丝赡軙?huì)覆寫(xiě)這些方法势决,并于其中做一些無(wú)法在回首階段安全之行的操作。此外蓝撇,屬性可能正處于“鍵值觀測(cè)”(Key-Value Observation果复, KVO)機(jī)制的監(jiān)控之下,該屬性的觀察者(observer)可能會(huì)在屬性值改變時(shí)“保留”或使用這個(gè)即將回收的對(duì)象唉地。
要點(diǎn)###
- 在dealloc方法里据悔,應(yīng)該做的事情就是釋放指向其他對(duì)象的引用,并取消原來(lái)訂閱的“鍵值觀測(cè)”(KVO)或NSNotificationCenter等通知耘沼,不要做其他事情极颓。
- 如果對(duì)象持有文件描述符等系統(tǒng)資源,那么應(yīng)該專(zhuān)門(mén)寫(xiě)一個(gè)方法來(lái)釋放此種資源群嗤。這樣的類(lèi)要和其使用者約定:用完資源后必須調(diào)用close方法菠隆。
- 執(zhí)行異步任務(wù)的方法不應(yīng)該在dealloc里調(diào)用;只能在正常狀態(tài)下執(zhí)行的那些方法也不應(yīng)在dealloc里調(diào)用狂秘,因?yàn)榇藭r(shí)對(duì)象已處于正在回收的狀態(tài)了骇径。
文/z_zero(簡(jiǎn)書(shū)作者)原文鏈接:http://www.reibang.com/p/8829f7a09475著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)者春,并標(biāo)注“簡(jiǎn)書(shū)作者”破衔。