一次关于runloop的纠错探索之旅
做iOS也好几年了,前不久发现自己之前对FPS、runloop、NSTimer、CADisplayLink的认知竟然一直是错误的,把自己的思考过程写出来,希望能让更多的小伙伴有个较为深入的了解。
几个思考题
先问几个问题,来验证一下你需要不需要往下看。
- FPS是什么?它和runloop有没有关系?
- Timer和runloop的关系?Timer的时间最小可以设置为多少?
- CADisplayLink比NSTimer两种计时器的异同?
如果你不能很快的说出答案,那就往下看吧!
以前的错误认知
先说一下之前的错误认知
- 之前一直以为FPS刷新的频率是60次/秒,那么runloop执行的频率也就是60次/秒。
- runloop执行一次的时间是0.016毫秒,所以Timer计时器的设置最小就是0.016毫秒。
- 当runloop执行耗时操作时,NSTimer的事件会被跳过,无法执行,CADisplayLink不会跳过,所以比NSTiemr执行的更精准。
正确的逻辑
首先说第一个问题,FPS是屏幕的刷新频率,是由硬件触发的。而runloop是由事件触发的,平时处于休眠状态,等待唤醒,两者之间并没有任何关系。
第一个问题的结论是runloop的执行没有时间限制,所以一个runloop周期可能很短,也可能很长(有耗时操作),NSTimer注册的事件能不能得到执行就要看runloop的执行时间了。理论上来说,NSTimer设置的时间间隔只要大于一个runloop执行的周期那么它的事件就能得到执行。
第三个问题,CADisplayLink的执行时机和屏幕刷新是一致的,大概是16.67ms。与NSTimer相比,它的时间间隔是固定的,而NSTimer的时间间隔可以自行设置。但相同的是,如果碰到runloop执行耗时操作,CADisplayLink的事件也会被跳过。
末尾的话
凡事多问几个为什么,把零散的知识多结合起来思考,对一个事物的理解就会越深,也就会越接近真相。上面就是我对这个问题的思考,有不对的地方还希望各位朋友指正!有什么不同的想法也可以评论里说出来一起讨论
参考文章
深入理解runloop