ios NSTimer与保留环

创建NSTimer有下面三中方式

A timer object can be registered in only one run loop at a time, although it can be added to multiple run loop modes within that run loop. There are three ways to create a timer:

简单来说scheduledTimerWithTimeInterval不需要手动加到runloop,其他两个需要手动加,这里要注意要加的runloop的哪个模式上,scheduledTimerWithTimeInterval是加到default mode上,但是这个导致当runloop在非default mode上时,timer处理函数无法触发。这时用后两种函数就可以要把timer加到NSRunLoopCommonModes伪模式上。

Run Loop不能在运行在NSRunLoopCommonModes,因为NSRunLoopCommonModes是个Mode集合,而不是一个具体的Mode。我们可以在添加事件源的时候使用NSRunLoopCommonModes,只要Run Loop运行在NSRunLoopCommonModes中任何一个Mode,这个事件源都可以被触发。

这里要讨论的主要是反复执行的计时器,容易引入保留环的问题。
1.NSTimer对象会保留目标,直到其失效为止,调用invalidate可以让其失效,或者一次性计时器触发任务完成之后。
2.反复执行的任务可能导致保留环的发生。如果目标对象保留了计时器,那么就形成了保留环,如果不再相应的时机人为打破保留环,那么内存就泄露了。
3.采用扩展NSTimer来解决2的问题。



  1. @interface NSTimer (EOCBlocksSupport)  
  2.   
  3. + (NSTimer *)eoc_scheduledTimerWithTimeInterval:(NSTimeInterval)interval  
  4.                                           block:(void(^)())block  
  5.                                         repeats:(BOOL)repeats;  
  6.   
  7. @end  
  8.   
  9. @implementation NSTimer (EOCBlocksSupport)  
  10.   
  11. + (NSTimer *)eoc_scheduledTimerWithTimeInterval:(NSTimeInterval)interval  
  12.                                           block:(void(^)())block  
  13.                                         repeats:(BOOL)repeats  
  14. {  
  15.     return [self scheduledTimerWithTimeInterval:interval  
  16.                                          target:self  
  17.                                        selector:@selector(eoc_blockInvoke:)  
  18.                                        userInfo:[block copy]  
  19.                                         repeats:repeats];  
  20. }  
  21.   
  22. + (void)eoc_blockInvoke:(NSTimer*)timer {  
  23.     void (^block)() = timer.userInfo;  
  24.     if (block) {  
  25.         block();  
  26.     }  


在xxxViewContoler里面使用这个扩展。

  1. -(void)startPolling {
         __weak EOCClass * weakself  = self;
         _pollTimer =   eoc_scheduledTimerWithTimeInterval:5.0  
  2.                                           block:^ {
  3.                                           EOCClass *strongSelf = weakself;
  4.          //上边代码也可以用__strong来修饰强关系,这里面应该是变为autoReleaseing的了。可以保证在这个作用于范围使用。
  5.                                           [strongSelf doReFresh];
  6.                                         }  
  7.                                         repeats:(BOOL)YES;
  8. }

此处使用__weak还能让程序更加安全,倘若开发者在delloc的时候忘记调用invalidate,从而使定时器在运行【这里就有疑问了,xxxcontroller持有timer,当控制器回收时timer也应该引用数为0啊,原因是这里runloop还会持有一份引用。】, 倘若这样的事情发生,weakself会变为nil
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值