解决NSTimer循环引用Retain Cycle问题

解决NSTimer循环引用Retain Cycle问题

iOS开发中以下的情况会产生循环引用

  1. block
  2. delegate
  3. NSTimer

循环引用导致一些对象无法销毁,一定的情况下会对我们横须造成影响,特别是我们要在dealloc中释放一些资源额时候,本篇主要解决NSTimer引起的循环引用问题。

问题分析

主要由于NSTimer对象和调用NSTimer的视图控制器对象相互强引用了,其中NSTimer对视图控制器的引用发生在最后一个参数reapets为YES的时候,因为需要重复执行操作,所以需要强引用调用对象,那么解决办法有两点

  1. 让视图控制器对NSTimer的引用变成弱引用
  2. 让NSTimer对视图控制器的引用变成弱引用

分析一下两种方法,第一种方法如果控制器对NSTimer的引用改为弱引用,则会出现NSTimer直接被回收,所以不可使,因此我们只能从第二种方法入手

解决办法:使用一个NSTimer的Catagory,然后重写初始化方法,在实现中利用block,从而在调用的时候可以使用weakSelf在block执行任务,从而解除NSTimer对target(视图控制器)的强引用。

注:在iOS10中苹果为NSTimer类添加了带有block的初始化方法,解决了上述问题,实现的原理是一样的,但是我们要为了项目的各个系统版本的兼容,我们用分类增加了一个方法进行实现。

问题解决

我们为NSTimer添加Category方法

使用:

//添加计时器
-(void)addTiemrWeak{
    __weak typeof(self)weakSelf = self;
    self.timer = [NSTimer wk_scheduledTimerWithTimeInterval:1.0 repeats:YES handlerBlock:^void(void){
        __strong typeof(weakSelf)strongSelf = weakSelf;

        //TO-DO...
    }];
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

//销毁计时器
-(void)destoryTimer{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
 }

-(void)dealloc{
    [self destoryTimer];
}

实例下载WeakTimer-Timer

原文地址:https://www.cnblogs.com/fengtengfei/p/6808970.html