RunLoop
Runloop:消息循环机制
一,概念:
OSX/iOS 系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。
CFRunLoopRef 是在 CoreFoundation 框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。
NSRunLoop 是基于 CFRunLoopRef 的封装,提供了面向对象的 API,但是这些 API 不是线程安全的。
二,NSRunLoopMode:
NSRunLoop三种model:
①defaultMode
②trackingMode
③commonModes(包含①,②两种模式)
程序大部分处于defaultMode状态,当scrollview滑动时,主线程runloop会自动切换成trackingMode状态(******此处注意只有主线程才会这样,子线程的default模式不会切换trackingmode模式)
主线程中设置Timer或CADisplayLink,通常会设置为commonModes属性,表示default和tracking模式下都会进行监听,避免滑动时无法回调(轮播图定时器模式设定common,否则滑动列表轮播图不走)
三,使用:
RunLoop是无法主动被创建的,只能通过在currentRunLoop或mainRunLoop获取到对应的RunLoop。
0,可以尝试将NSRunLoopCommonModes改成NSDefaultRunLoopMode,那么timerFired:函数在scrollview滑动的时候,就不会被定时调用了,直到滑动停止。
- 线程和RunLoop是一一对应的,且互相独立,比如主线程对应mainRunLoop,而子线程也是有它自己所对应的RunLoop。 b. 主线程的RunLoop在应用启动的时候就开始run了,而子线程是需要主动调用其run方法来启动。
2,NSRunLoop是需要source event才会一直运行的,否则运行完会被终止。这里通常会有两种source event:
a.异步事件,通常为addPort或performSelector:onThread方法;
b.Timer事件,通常为addTimer或performSelector:afterDelay(内部会创建一个Timer,并将Timer加入到当前线程对应的NSRunLoop中)等方法。
如果提前调用run方法,RunLoop没有设置任何source event,会立即终止,而执行到下边performSelector方法时,这时虽然设置了timer source,但RunLoop已经终止,也无法响应。
保活:
通过addPort方法可以使RunLoop监听某个端口的事件,从而保证其一直运行。
addPort设置mode为default,因为新开辟线程,不在主线程,所以scrollview滑动的时候mode模式也不会切换成tracking模式,也就是上面提到的注意点:只有主线程的RunLoop才会在滑动的时候切换为trackingmode模式
以后谈到优化的时候再谈runloop怎么对tableview加载大图进行优化。