iOS之NSTimer使用和注意事项

iOS之NSTimer

前言

大家在开发的过程中,如果对NSTimer用的不是很熟悉的情况下,极有可能会发生循环引用导致内存无法释放。以及当界面互动的时候,NSTimer会停止,滑动停止会又计时的问题

NSTimer的使用方法

比较常用的两个方法:

+ (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;

这两个方法都是创建一个定时器,第一方法创建需要之后,需要手动把添加Runloop中,不然不执行定时功能。第二方法不要自己加,系统自动加。例如:


NSTimer *timer = [NSTimer timerWithTimeInterval:3 target:self 
selector:@selector(timerAction) userInfo:nil repeats:YES];
// 加入RunLoop中
[[NSRunLoop mainRunLoop] addTimer:timer 
forMode:NSDefaultRunLoopMode];

当NSTimer加入到NSRunloop中的NSDefaultRunLoopMode模式会出现一个问题就是当页面有UICrollView滑动执行执行的模式是UITrackingRunLoopMode,NSDefaultRunLoopMode被挂起了,会导致定时器失效,等恢复为滑动结束时才恢复定时器。详情请了解ibireme的深入理解RunLoop文章。

需要定时器在 UIScrollView 滑动时也不影响的话,有两种解决方法:

  • 给NSTimer分别添加到UITrackingRunLoopMode 和 NSDefaultRunLoopMode这两个模式中:
[[NSRunLoop mainRunLoop] addTimer:timer 
forMode:NSDefaultRunLoopMode];
[[NSRunLoop mainRunLoop] addTimer:timer 
forMode: UITrackingRunLoopMode]; 
  • 给NSTimer添加NSRunLoop的NSRunLoopCommonModes中,平常用这中就可以了,比较简便来。
[[NSRunLoop mainRunLoop] addTimer:timer 
forMode: NSRunLoopCommonModes]; 

NSTimer新增的新方法

NSTimer在iOS10中推出了两个新的API,与上面的方法比较区别主要是selector换成Block回调,不过要是适配低版本还是尽量使用上面的两个方法。两个API如下:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval 
repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block 
API_AVAILABLE(macosx(10.12), 
ios(10.0), watchos(3.0), tvos(10.0));

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:
(BOOL)repeats block:(void (^)(NSTimer *timer))block 
API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

这两个方法的区别和上面两个一样。

NSTimer释放

当NSTimer不需要了,需要释放NSTimer时,如下:

// 停止定时器
[timer invalidate];
timer = nil;

NSTimer总结

  • 使用NSTimer比较方便快捷。

  • 创建NSTimer必须加入到Runloop中才能生效
    创建NSTimer都是要加到Runloop中的,不管是手动添加还是系统添加。

  • 当Timer加入到runloop的模式的NSDefaultRunLoopMode,当UIScrollView滑动的时候会暂时失效

  • 使用NSTimer会存在延时,计时不是很准。因为不管是一次性的还是周期性的timer的实际触发事件的时间,都会与所加入的RunLoop和RunLoop Mode有关,

    • 如果此RunLoop正在执行一个连续性的运算,timer就会被延时出发。
    • 重复性的timer遇到这种情况,如果延迟超过了一个周期,则会在延时结束后立刻执行,并按照之前指定的周期继续执行,这个延迟时间大概为50-100毫秒.
    • NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了.
    • 在对时间准确精度不要求特别高的话,使用NSTimer定时器。

结尾

总结了NStimer基本使用方法和特点。希望大家能够具体操作一下,慢慢理解。

你可能感兴趣的:(iOS之NSTimer使用和注意事项)