RunLoop 系列文章
深入浅出 RunLoop(一):初识
深入浅出 RunLoop(二):数据结构
深入浅出 RunLoop(三):事件循环机制
深入浅出 RunLoop(四):RunLoop 与线程
深入浅出 RunLoop(五):RunLoop 与 NSTimer
深入浅出 RunLoop(六):相关面试题
RunLoop 与 NSTimer
- 由前面的文章我们知道,
NSTimer
是由RunLoop
来管理的,NSTimer
其实就是CFRunLoopTimerRef
,他们之间是 toll-free bridged 的,可以相互转换; - 如果我们在子线程上使用
NSTimer
,就必须开启子线程的RunLoop
,否则定时器无法生效。
解决 tableview 滑动时 NSTimer 失效的问题
- 问题:由前面的文章我们知道,
RunLoop
同一时间只能运行在一种模式下,当我们滑动tableview
/scrollview
的时候RunLoop
会切换到UITrackingRunLoopMode
界面追踪模式下。如果我们的NSTimer
是添加到RunLoop
的KCFRunLoopDefaultMode
/NSDefaultRunLoopMode
默认模式下的话,此时是会失效的。 - 解决:我们可以将
NSTimer
添加到RunLoop
的KCFRunLoopCommonModes
/NSRunLoopCommonModes
通用模式下,来保证无论在默认模式还是界面追踪模式下NSTimer
都可以执行。 NSTimer
的创建方式
如果我们是通过以下方法创建的NSTimer
,是自动添加到RunLoop
的默认模式下的
[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"123");
}];
我们可以通过以下方法创建NSTimer
,来自定义添加到RunLoop
的某种模式下
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"123");
}];
[[NSRunLoop currentRunLoop] addTimer:timer forMode