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基本使用方法和特点。希望大家能够具体操作一下,慢慢理解。
网友评论