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