runloop的5个类
首先,Core Foundation中关于runloop的类:
1.CFRunLoopRef :Runloop对象
2.CFRunLoopModeRef:Runloop运行模式
3.CFRunLoopSourceRef:事件源(输入源)
4.CFRunLoopTimerRef:基于时间的触发器
5.CFRunLoopObserverRef:观察者,能够监听Runloop的状态
6.CFRunLoopModeRef:代表runloop的运行模式
runloop运行时,只能指定一个Mode,这个Mode又称为currentMode,然后runloop就执行currentMode中的source/Timer/observe。
如果需要切换Mode,只能退出RunLoop,再重新指定一个Mode进入,这样做是为了分隔开不同组的Source/Timer/Observer,让其不受影响。
runloop的5个mode
系统默认注册了5个mode
1.NSRunloopDefaultMode : App默认的mode,通常主线程是在这个模式下运行的
2.UITrackingRunloopMode : 界面跟踪Mode,用于界面控件(ScrollView,tableView等等)追踪触摸滑动,保证界面滑动时不受其他Mode影响
3.UIInitializationRunLoopMode : 在刚启动app时进入的第一个mode,启动完成之后就不再使用。
4.GSEventReceiveRunLoopMode : 接收系统事件的内部mode,通常用不到
NSRunLoopCommonMode : 这是一个占位mode,不是一种真正的mode,(可以看成模式组,默认情况下包括了NSRunloopDefaultMode 和 5.UITrackingRunloopMode)两种模式
runloop的5个状态
KCFRunloopEntry : 即将进入runloop
kCFRunLoopBeforeTimers : 即将处理timer
kCFRunLoopBeforeSources : 即将处理source(事件源)
kCFRunLoopBeforeWaiting :即将进入休眠
kCFRunLoopAfterWaiting : 即将从休眠中醒来
kCFRunLoopExit : 即将退出runloop
runloop与线程
1.每个线程都有唯一一个与之对应的runloop对象
2.主线程的runloop系统已经创建好了,子线程的runloop需要手动创建
3.runloop在第一次获取时由系统自动创建,在线程结束时销毁
如果想给子线程创建RunLoop,不能直接alloc&init,只要调用获取当前线程RunLoop方法即可,系统会自动放回当前线程的RunLoop,如果当前线程没有RunLoop,系统会自动创建.
runloop处理逻辑
如果runloop中没有Timer或者source,Runloop会立刻退出。
每次运行runloop,runloop会自动处理之前未处理的消息,并通知相应的观察者。具体的顺序如下:
1.通知观察者runloop已经启动
2.通知观察者即将启动定时器
3.通知观察者即将启动非基于端口的事件源
4.启动任何准备好的非基于端口的事件源
5.如果基于端口的事件源准备好并且进入等待状态,立即启动,并进入步骤九
6.通知观察者线程进入休眠
7.将线程置于休眠直到下面任何事件的发生
(1)某一事件到达基于端口的源
(2)定时器启动
(3)RunLoop设置的时间已经超时.(系统底层会给RunLoop设置一个超时时间,源码中设置的是:9999999999.0)
(4)RunLoop被手动唤醒
8.通知观察者线程将被唤醒
9.处理未处理的事件
(1)如果用户定义的定时器启动,处理定时器事件并重启RunLoop.进入步骤2
(2)如果事件源启动,传递相应的消息
(3) 如果RunLooop被显示唤醒而且时间还没超时,重启RunLoop.进入步骤2
10.通知观察者runloop结束
网友评论