概念
- RunLoop类似于Windows程序的消息循坏,不断的循环处理事件消息(定时器事件,用户交互事件,模态窗口事件,系统Source事件,自定义Source事件)
- RunLoop和线程是一一对应的,直到在线程中获取的时候,RunLoop才创建
- RunLoop包括3大核心组建:定时器,输入源Input Sources和观察者Observer
RunLoop的Modes
- Modes是一组事件类型的集合,每个事件是注册关联到一个或者多个Mode中,RunLoop在每个时刻运行在一个特定的模式
- RunLoop在运行时,只注册到当前模式下的事件和通知模式相关的观察者
- NSDefaultRunLoopMode
- NSRunLoopCommonModes
- TrackingRunLoopMode
Observer
* CFRunLoopActivity定义了RunLoop在运行中不同的活动状态,这些状态可以通过观察者Observer跟踪
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0),
kCFRunLoopBeforeTimers = (1UL << 1),
kCFRunLoopBeforeSources = (1UL << 2),
kCFRunLoopBeforeWaiting = (1UL << 5),
kCFRunLoopAfterWaiting = (1UL << 6),
kCFRunLoopExit = (1UL << 7),
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
定时器
- 当其加入到 RunLoop 时,RunLoop会注册对应的时间点,当时间点到时,RunLoop会被唤醒以执行那个回调
Input Source
- 基于Port的Source
- Perform Selector Sources
- 自定义Source
RunLoop事件处理流程
RunLoop事件处理流程
- 通知观察者即将进入runloop处理
- 如果存在即将发生的定时器事件,通知所有的观察者。
- 如果存在即将发生的非port的source事件,在事件发生前,通知所有的观察者。
- 如果存在即将发生的非port的source事件,在事件发生后,通知所有的观察者。
- 如果存在基于port的事件等待处理,立即处理转9
- 通知观察者,线程即将休眠
- 线程休眠一直等到下面任意事件之一发生:
- 基于port的事件发生
- 定时器超时
- runloop设置的超时时间到期
- 显式的唤醒runloop
- 通知观察者,线程即将被唤醒
- 处理等待的事件
- 如果是定时器事件,执行定时器处理函数重新start runloop, 转2
- 如果是用户定义的source 执行对应的事件处理方法
- 如果runloop被显式的唤醒并且没有超时,重新start runloop, 转2
RunLoop的使用
- AutoreleasePool
- 事件响应
- 手势识别
- 界面更新
- 定时器
- PerformSelector