哎呦,NSRunLoop是何方圣神?(关于NSRunLoop推荐看一下孙源@sunnnyxx的分享视频)
其实从字面上就可以看出来,RunLoop就是跑圈, 保证程序一直在执行. App运行起来之后, 即使你什么都不做, 放在那儿它也不会退出, 而是一直在"跑圈",这就是RunLoop干的事. 主线程会自动创建一个RunLoop来保证程序一直运行. 但子线程默认不创建NSRunLoop, 所以子线程的任务一旦返回,线程就over了。
RunLoop在某一时刻只能在一种模式下运行,更换模式时需要暂停当前的Loop, 然后重启新的Loop. RunLoop主要有下面几个模式
NSDefalutRunLoopMode: 默认Mode, 通常主线程在这个模式下运行
UITrackingRunLoopMode: 滑动ScrollView是会切换到这个模式
NSRunLoopCommonModes:包括上面两个模式
这边需要特别注意的是,在滑动ScrollView的情况下, 系统会自动把RunLoop模式切换成UITrackingRunLoopMode来保证ScrollView的流畅性.
当你在滑动ScrollView的时候上面的timer会失效,原因是Timer是默认加在NSDefalutRunLoopMode上的,而滑动ScrollView后系统把RunLoop切换为UITrackingRunLoopMode, 所以timer就不会执行了。
解决方法如下:把该Timer加到NSRunLoopCommonModes下, 这样即使滑动ScrollView也不会影响timer了.
另外还有一个trick是当tableview的cell从网络异步加载图片时,加载完成后在主线程刷新显示图片, 这时滑动tableview会造成卡顿,咋办呢?
通常的思路是tableview滑动的时候延迟加载图片, 等停止滑动时再显示图片.这里我们可以通过RunLoop来实现:
当NSRunLoop为NSDefaultRunLoopMode的时候tableview肯定停止滑动了,为啥? 因为如果还在滑动中, RunLoop的mode应该是UITrackingRunLoopMode。