NSTimer 的使用

2019-04-20  本文已影响0人  yyggzc521

使用方法

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

scheduledTimerWith和timerWith和区别

NSTimer是加到runloop中执行的。

  1. scheduledTimerWith
    函数说明,创建并安排到runloop的default mode中

Creates a timer and schedules it on the current run loop in the default mode

  1. timerWithTimeInterval
    如果我们调用的是timerWith接口,就需要自己加入runloop
NSTimer *timer  =  [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(Timered) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

GCD定时器

如何使用

GCD中的Dispatch Source其中的一种类型是DISPATCH_SOURCE_TYPE_TIMER,可以实现定时器的功能。注意的是需要把timer声明为属性,否则,由于这种timer并不是添加到runloop中的,直接就被释放了。

GCD定时器的好处是,他并不是加入runloop执行的,因此子线程也可以使用。也不会引起循环引用的问题。

WS(weakSelf);
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
    [weakSelf commentAnimation];
});
dispatch_resume(timer);

注意事项

子线程启动NSTimer

主线程默认启动了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的target被强引用了,而通常target就是所在的控制器,他又强引用了timer,造成了循环引用

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

不是解决了循环引用,target就可以释放了,别忘了在持有timer的类dealloc的时候执行invalidate。

NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Timered:) userInfo:nil repeats:YES];

如上面代码,这个timer并没有被self引用,那么为什么self不会被释放呢?因为timer被加到了runloop中,timer又强引用了self,所以timer一直存在的话,self也不会释放。

参考资料

https://www.jianshu.com/p/3ccdda0679c1

上一篇 下一篇

猜你喜欢

热点阅读