美文网首页准备
解决NSTimer的循环引用问题

解决NSTimer的循环引用问题

作者: 丶墨墨丶 | 来源:发表于2018-11-21 11:20 被阅读13次

    一、首先介绍NSTimer一些其他注意点

    1.scheduledTimerWith的函数创建并安排到runloop的default mode中。会出现其他mode时timer得不到调度的问题。最常见的问题就是在UITrackingRunLoopMode,即UIScrollView滑动过程中定时器失效。

    解决方式就是把timer add到runloop的NSRunLoopCommonModes。

    2.iOS是通过runloop作为消息循环机制,主线程默认启动了runloop,可是子线程没有默认的runloop,因此,我们在子线程启动定时器是不生效的。

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSTimer* timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(Timered:) userInfo:nil repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
            [[NSRunLoop currentRunLoop] run];
        });
    

    二、不是所有的NSTimer都会造成循环引用。就像不是所有的block都会造成循环引用一样。以下两种timer不会有循环引用:

    非repeat类型的。非repeat类型的timer不会强引用target,因此不会出现循环引用。

    block类型的,新api。iOS 10之后才支持,因此对于还要支持老版本的app来说,这个API暂时无法使用。当然,block内部的循环引用也要避免。

    注意点:timer被加到runloop中,不会自动释放,不是解决了循环引用,target就可以释放了,别忘了在持有timer的类dealloc的时候执行invalidate。

    找到的一些解决办法

    - (void)viewDidLoad {
        [super viewDidLoad];
        __weak id weakSelf = self;
        NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer *timer) {
            NSLog(@"block %@",weakSelf);
        }];
    }
    
    @implementation NSTimer(BlockTimer)
    + (NSTimer*)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats blockTimer:(void (^)(NSTimer *))block{
        NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(timered:) userInfo:[block copy] repeats:repeats];
        return timer;
    }
    
    + (void)timered:(NSTimer*)timer {
        void (^block)(NSTimer *timer)  = timer.userInfo;
        block(timer);
    }
    @end
    

    解释:将强引用的target变成了NSTimer的类对象。类对象本身是单例的,是不会释放的,所以强引用也无所谓。执行的block通过userInfo传递给定时器的响应函数timered:。循环引用被打破的结果是:

    timer的使用者强引用timer。
    timer强引用NSTimer的类对象。
    timer的使用者在block中通过weak的形式使用,因此是被timer弱引用。

    相关文章

      网友评论

        本文标题:解决NSTimer的循环引用问题

        本文链接:https://www.haomeiwen.com/subject/yjpqqqtx.html