runloop的状态
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry , // 进入 loop
kCFRunLoopBeforeTimers , // 触发 Timer 回调
kCFRunLoopBeforeSources , // 触发 Source0 回调
kCFRunLoopBeforeWaiting , // 等待 mach_port 消息
kCFRunLoopAfterWaiting , // 接收 mach_port 消息
kCFRunLoopExit , // 退出 loop
kCFRunLoopAllActivities // loop 所有状态改变
}
runloop的简化逻辑
int32_t __CFRunLoopRun() {
// 1. 通知 Observers:即将进入 RunLoop
__CFRunLoopDoObservers(KCFRunLoopEntry);
do {
// 2. 通知Observers:即将要处理 timer
__CFRunLoopDoObservers(kCFRunLoopBeforeTimers);
// 3. 通知Observers:即将要处理 source
__CFRunLoopDoObservers(kCFRunLoopBeforeSources);
// 处理非延迟的主线程调用
__CFRunLoopDoBlocks();
// 处理 UIEvent 事件
__CFRunLoopDoSource0();
// GCD dispatch main queue
CheckIfExistMessagesInMainDispatchQueue();
// 4. 通知 Observers:即将进入休眠等待
__CFRunLoopDoObservers(kCFRunLoopBeforeWaiting);
// 等待内核mach_msg事件
mach_port_t wakeUpPort = SleepAndWaitForWakingUpPorts();
// mach_msg_trap
// 休眠中 Zzz...
// Received mach_msg, wake up
// 5. 通知 Observers:从休眠等待中醒来
__CFRunLoopDoObservers(kCFRunLoopAfterWaiting);
if (wakeUpPort == timerPort) {
// 处理因timer的唤醒
__CFRunLoopDoTimers();
} else if (wakeUpPort == mainDispatchQueuePort) {
// 处理异步方法唤醒,如:dispatch_async
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__()
} else {
// UI 刷新,动画显示
__CFRunLoopDoSource1();
}
// 再次确保是否有同步的方法需要调用
__CFRunLoopDoBlocks()
} while(!stop && !timeout);
// 6. 通知 Observers:即将退出runloop
__CFRunLoopDoObservers(CFRunLoopExit);
}