NSTimer 的内存泄露问题
2016-06-12 21:55
218 查看
正常来讲,我们开启一个Timer有几种办法,
1. 直接使用
这个不用关心runloop的事情,也不用关心mode,默认添加到当前runloop的默认mode
2. 首先创建Timer 然后添加到runloop里面。
这里的添加的runloop里面还要选择mode,所以注意可能会阻塞runloop里面的相同mode下的其他进程(比如滚动tableview,timer暂停)。这是个坑。需要注意。
. This means that as long as a timer remains valid, its target will not be deallocated
这样self如果是controller,controller 被 pop 的时候就会发生内存泄露,因而不会被销毁。解决方法首先是在
停止timer,并且置为nil,不过这样再pop回来timer就没了,就要重新启动timer,如果也有倒计时的话,计数就不对了。比较经济实惠的方法是用block解决。大概想法就是让Nstimer 类做为target,解决内存无法释放的问题。
注意:以上NSTimer的target是NSTimer类对象,类对象本身是个单利,此处虽然也是循环引用,但是由于类对象不需要回收,所以没有问题。但是这种方式要注意block的间接循环引用,当然了,解决block的间接循环引用很简单,定义一个weak变量,在block中使用weak变量即可。
1. 直接使用
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
这个不用关心runloop的事情,也不用关心mode,默认添加到当前runloop的默认mode
2. 首先创建Timer 然后添加到runloop里面。
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
这里的添加的runloop里面还要选择mode,所以注意可能会阻塞runloop里面的相同mode下的其他进程(比如滚动tableview,timer暂停)。这是个坑。需要注意。
内存泄露
内存泄露的原因是Timer不停止,则会一直保有一份target(比如self),. This means that as long as a timer remains valid, its target will not be deallocated
这样self如果是controller,controller 被 pop 的时候就会发生内存泄露,因而不会被销毁。解决方法首先是在
- (void)viewWillDisAppear
停止timer,并且置为nil,不过这样再pop回来timer就没了,就要重新启动timer,如果也有倒计时的话,计数就不对了。比较经济实惠的方法是用block解决。大概想法就是让Nstimer 类做为target,解决内存无法释放的问题。
@interface NSTimer (XXBlocksSupport) + (NSTimer *)xx_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats; @end @implementation NSTimer (XXBlocksSupport) + (NSTimer *)xx_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats { return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(xx_blockInvoke:) userInfo:[block copy] repeats:repeats]; } + (void)xx_blockInvoke:(NSTimer *)timer { void (^block)() = timer.userinfo; if(block) { block(); } } @end
注意:以上NSTimer的target是NSTimer类对象,类对象本身是个单利,此处虽然也是循环引用,但是由于类对象不需要回收,所以没有问题。但是这种方式要注意block的间接循环引用,当然了,解决block的间接循环引用很简单,定义一个weak变量,在block中使用weak变量即可。
相关文章推荐
- c语言内存泄露示例解析
- 解决js函数闭包内存泄露问题的办法
- IE下使用jQuery重置iframe地址时内存泄露问题解决办法
- Android App调试内存泄露之Cursor篇
- js内存泄露的几种情况详细探讨
- Javascript 闭包引起的IE内存泄露分析
- JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
- 深入解析PHP垃圾回收机制对内存泄露的处理
- PHP脚本内存泄露导致Apache频繁宕机解决方法
- 容易造成JavaScript内存泄露几个方面
- 关于js内存泄露的一个好例子
- 总结JavaScript在IE9之前版本中内存泄露问题
- Android垃圾回收机制解决内存泄露问题
- Android编程中避免内存泄露的方法总结
- C语言中的内存泄露 怎样避免与检测
- PHP CURL 内存泄露问题解决方法
- Java中典型的内存泄露问题和解决方法
- Android中Handler引起的内存泄露问题解决办法
- 浅谈Java编程中的内存泄露情况
- iOS中的NSTimer定时器的初步使用解析