一、温故而知新:
看完自己文章《解决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
一起被销毁了。