一、溫故而知新:
看完自己文章《解決NSTimer迴圈引用導致記憶體洩漏的三種方法》之後有新的感悟,所以在此針對第三種方法做重點總結。
GitHub地址TFQWeakTimer
二、TFQWeakTimer
使用方法
1、將TFQWeakTimer
檔案拖到自己專案中。
2、匯入"TFQWeakTimer.h"
通過initWithXXX
方法建立定時器.
3、在需要銷燬TFQWeakTimer
或者當前類dealloc
的時候呼叫TFQWeakTimer
中的物件方法invalidateTimer
銷燬TFQWeakTimer
demo
中TFQSecondController
類建立了定時器,首先可以確定的一點是,就算TFQWeakTimer
不銷燬,TFQSecondController
也是可以銷燬的。因為沒有人強引用TFQSecondController
。等TFQWeakTimer
任務執行完以後就自己銷燬了。
這中解決迴圈引用的方法應用到了《大話設計模式》中的代理模式,見我的另一篇文章大話設計模式,裡邊有23種設計模式的demo。
三、畫圖解釋
- 迴圈引用:
TFQSecondController
強引用NStimer
。NStimer
新增在runloop
上,只要NStimer
不取消對TFQSecondController
的強引用,TFQSecondController
就銷燬不了。當然了你可以選擇在viewWillDisappear
中銷燬NStimer
。但是TFQSecondController
頁面不一定都是pop
到上一個頁面的時候才會呼叫viewWillDisappear
方法,也有可能push
新頁面,也有可能是進入後臺的時候呼叫viewWillDisappear
,這樣我們希望重新回到定時器頁面的時候,定時任務還依舊是執行狀態。所以invalidate
放到viewWillDisappear
是不合理的,唯一合理的地方就是TFQSecondController
銷燬的時候銷燬timer
。所以如果NStimer
在頁面即將銷燬的時候任務還沒執行完的話,那麼它的的invalidate
方法只能放到TFQSecondController
的dealloc
中。
圖中兩個類互相引用,彼此無法銷燬,能銷燬的唯一辦法就是NSTimer
任務結束,不再持有TFQSecondController
,如果任務一直迴圈的話當前類就無法銷燬,造成記憶體洩漏。
- 用代理模式解決迴圈引用:圖中已經能非常明顯的看出來
TFQSecondController
是可以隨時銷燬的,只要在TFQSecondController
的dealloc
方法中呼叫TFQWeakTimer
的invalidateTimer
方法,TFQWeakTimer、NSTimer
就可以隨著TFQSecondController
一起被銷燬了。