RunLoop

作者: 言霏 | 来源:发表于2020-07-20 17:25 被阅读0次

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);
}

相关文章

网友评论

      本文标题:RunLoop

      本文链接:https://www.haomeiwen.com/subject/xdpykktx.html