CFRunLoopObserverRef 是观察者,每个 Observer 都包含了一个回调(函数指针),当 RunLoop 的状态发生变化时,观察者就能通过回调接受到这个变化。可以观测的时间点有以下几个:
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), // 即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理 Timer
kCFRunLoopBeforeSources = (1UL << 2), // 即将处理 Source
kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), // 即将退出Loop
};
文集中提到的激活 RunLoop 的 input source 事件源, 他们会产生 同步(synchronous "timer")或者异步(asynchronous custom source等),与之对应, runloop 的 observers 将会在 runloop 运行到某个状态时候自动触发. 你可以在 runloop 即将处理某个事件时使用observers 进行某项操作,或者使用 observers 对 runloop 进入睡眠时候去控制 thread. 简而言之, RunLoop Observer 则在 RunLoop 本身进入某个状态时候得到通知
你可以创建一个 Observer 对 RunLoop 的如下状态进行观察:
RunLoop 进入时候
RunLoop 将要处理一个 Timer 时候
RunLoop 将要处理一个 Input Source时候
RunLoop 将要进入睡眠的时候
RunLoop 将要被唤醒的时候,在唤醒它的事件被处理之前
RunLoop 停止的时候
你可以用 CoreFoundation 的 API 给 RunLoop 添加 observers.使用CFRunLoopObserverRef 创建一个 runloop observer 的实例. 在创建实例时候, 给 observer 配置 callbacks 来跟踪 runloop的状态.
与 timer 类似, runloop observers 可以被声明成 once 一次 或者 repeat 重复监控. 一次性的 observer 会在它被触发,完成相关操作就从 runloop 中移除监控, repeat 类型还会继续监听. 当你创建一个 observers 你就应该指定是once 还是 repeat.