“自釋放”在iOS開發中的應用

發表於2016-03-15
今天,跟大家聊聊“自釋放”思想在iOS開發中的應用,何為“自釋放”?可以簡單的理解為物件在生命週期結束後自動清理回收所有與其相關的資源或連結,這個清理不僅僅包括物件記憶體的回收,還包括物件解耦以及附屬事件的清理等,比如定時器的自我停止、KVO物件的監聽移除等

物件記憶體的回收

開發中,物件管理的基本原則——誰建立誰釋放。但是,非ARC工程中,我們會用autorelease來標記一個物件,告訴編輯器,這個物件我不負責釋放,此時,這個物件就變成了“自釋放”物件,當其不再需要時,系統就會自動回收其記憶體。而ARC工程中,所有物件對於我們來說都是自釋放物件,很高興,我們不再需要處處留意記憶體洩露的問題,可以把更多的精力放在業務邏輯上,但是這並不意味著真的沒有記憶體洩露,試試這個工具HJNSObjectRelease,也許你會有意想不到的收穫。

定時器的自釋放

定時器與一般物件不同,當建立完定時器後,其並不會自我釋放,需要在適當時刻invalidate。在實際開發中,也許你經常會這樣建立定時器

然後在dealloc函式中將定時器invalidate。很遺憾,你會發現程式永遠也不會執行到dealloc函式,因為NSTimer強引用target物件,迴圈引用的出現必然導致記憶體洩露。此時,你肯定非常想要一個weak target的定時器,很高興,MSWeakTimer很好的滿足了你的需求。但是,Timer仍然沒有自我釋放,你仍然需要在dealloc中將其invalidate。那麼,如何才能不寫invalidate?定時器能否自釋放?我們先把這個問題放在一邊,接著往下看

KVO的自釋放

iOS開發中,經常會用到訊息通知及KVO,也許你會這樣寫程式碼

隨著時間的積累,你會非常習慣這種寫法,並且蘋果也是這樣推薦的。但是慢慢你會發現所有物件的Dealloc函式都只做了這一件事,能不能不做這件事?FBKVOController也許會是一個不錯的選擇,Demo可以這樣寫

FBKVOController的實現原理可以檢視這篇文章,通過自釋放的實現,程式猿不再關心remove監聽。但是其還是有一定的侷限性——物件無法監聽自己的屬性,如果你的程式碼是這樣的

很遺憾,迴圈引用的問題又出現,因為FBKVOController中的NSMapTable物件會retain key物件,具體程式碼如下

那麼,FBKVOController是如何做到自釋放的?可以歸納為四個字——動態屬性。其為觀察者繫結動態屬性self.KVOController,動態繫結的KVOController會隨著觀察者的釋放而釋放,KVOController在自己的dealloc函式中移除KVO監聽,巧妙的將觀察者的remove轉移到其動態屬性的dealloc函式中。

可是,這又有什麼用?物件仍然無法監聽自己的屬性,還是要重寫set函式。HTBKVObservation也許會改變你的想法,其和FBKVOController來自同一人,程式碼可以這樣寫

HTBKVObservation並沒用採用動態屬性,而是採用屬性的方式實現自釋放。可以監控物件自己的屬性,但是需要建立屬性HTBKVObservation。 這裡我對其做了一點擴充套件,方便使用,程式碼可以這樣寫

FBKVOController 和HTBKVObservation通過屬性或動態屬性巧妙的將KVO的remove轉移給第三者,實現了KVO事件的解耦,為自釋放的實現提供了一種借鑑思路

NSNotification的自釋放

談完 KVO,再來談談NSNotification。針對Notification,ReactiveCocoa做了很好的封裝,網上有很多介紹其如何使用的文章,在此不再累述。直接看程式碼

簡單明瞭,當觀察者dealloc,很遺憾,NSNotification並沒用移除,因為物件並沒用自釋放,正確程式碼應該是這樣

ReactiveCocoa自釋放的原理與FBKVOController不同,其並不是通過屬性或者動態屬性的方式實現,而是通過swizzling觀察物件的dealloc函式,在自定義dealloc函式實施清理,但不是預設清理,需要我們告訴它willDeallocSignal的時候完成所有清理工作。

除了定時器、KVO、NSNotification,包括封裝的某個功能物件,比如HttpRequest,或者資料庫ListSql等,合理的利用自釋放可以給使用者帶來更多的便利,同時也會減少 crash 產生的概率。實現自釋放的方法可以總結為以下三種方式

  1.  動態屬性的自釋放
  2. @property 的自釋放
  3. swizzling dealloc的自釋放

可以根據具體業務或者設計思想選擇對應的實現方式,這是一種思想,更是一個習慣。相信你會愛上它,畢竟誰不喜歡簡潔的實現方式了!

相關文章