iOS学习笔记iOS开发记录iOS程序猿

RunLoop 源码阅读

2018-05-24  本文已影响29人  cdcyd
  1. 获取runloop的函数
// 获取主线程的runloop
CFRunLoopRef CFRunLoopGetMain(void) {
    CHECK_FOR_FORK();
    static CFRunLoopRef __main = NULL; // no retain needed
    if (!__main) __main = _CFRunLoopGet0(pthread_main_thread_np()); // no CAS needed
    return __main;
}

// 获取子线程的runloop
CFRunLoopRef CFRunLoopGetCurrent(void) {
    CHECK_FOR_FORK();
    CFRunLoopRef rl = (CFRunLoopRef)_CFGetTSD(__CFTSDKeyRunLoop);
    if (rl) return rl;
    return _CFRunLoopGet0(pthread_self());
}
  1. 创建runloop的函数
CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
    // 判断t所指向的线程是否为空,如果为空,就获取当前的主线程进行赋值
    if (pthread_equal(t, kNilPthreadT)) {
        t = pthread_main_thread_np();
    }
    __CFLock(&loopsLock);

    // 全局__CFRunLoops,它是一个字典,用来存储所有线程的runloop
    if (!__CFRunLoops) {
        __CFUnlock(&loopsLock);
        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
        // 由于主线程默认就有runloop,所以再创建__CFRunLoops,要默认添加一个主线程的runloop
        CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());
        CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);
        if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) {
            CFRelease(dict);
        }
        CFRelease(mainLoop);
        __CFLock(&loopsLock);
    }

    // 从__CFRunLoops中获取对应于当前线程的RunLoop
    CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
    __CFUnlock(&loopsLock);
    if (!loop) {
        // 如果没有取到,说明是第一次,则创建一个runloop加入到全局字典中
        CFRunLoopRef newLoop = __CFRunLoopCreate(t);
        __CFLock(&loopsLock);
        loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
        if (!loop) {
            // 存储当前线程和对应的RunLoop到全局字典__CFRunLoops中
            CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);
            loop = newLoop;
        }
        __CFUnlock(&loopsLock);
        CFRelease(newLoop);
    }

    // 判断是否为当前线程,如果是就注册一个回调,当线程销毁时,也销毁其对应的 RunLoop
    if (pthread_equal(t, pthread_self())) {
        _CFSetTSD(__CFTSDKeyRunLoop, (void *)loop, NULL);
        if (0 == _CFGetTSD(__CFTSDKeyRunLoopCntr)) {
            _CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS-1), (void (*)(void *))__CFFinalizeRunLoop);
        }
    }
    return loop;
}
  1. 运行runloop的函数
void CFRunLoopRun(void) {
    // 只有运行完成或主动退出时,才会真正的退出
    int32_t result;
    do {
        result = CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false);
        CHECK_FOR_FORK();
    } while (kCFRunLoopRunStopped != result && kCFRunLoopRunFinished != result);
}

SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) {  
    CHECK_FOR_FORK();
    // 判断RunLoop是否正在被销毁,已被销毁就退出原因
    if (__CFRunLoopIsDeallocating(rl)) return kCFRunLoopRunFinished;

    __CFRunLoopLock(rl);

    // 获取当前 mode
    CFRunLoopModeRef currentMode = __CFRunLoopFindMode(rl, modeName, false);
    if (NULL == currentMode || __CFRunLoopModeIsEmpty(rl, currentMode, rl->_currentMode)) {
        // 如果当前 mode 和 runloop 的 mode 都为 nil,则退出
        Boolean did = false;
        if (currentMode) __CFRunLoopModeUnlock(currentMode);
        __CFRunLoopUnlock(rl);
        return did ? kCFRunLoopRunHandledSource : kCFRunLoopRunFinished;
    }

    // 保存正在运行的RunLoop,把相关数据压进栈
    volatile _per_run_data *previousPerRun = __CFRunLoopPushPerRunData(rl);
    CFRunLoopModeRef previousMode = rl->_currentMode;
    rl->_currentMode = currentMode;
    int32_t result = kCFRunLoopRunFinished;

    // 判断是否可以运行runloop,并通知观察者Observer,即将运行RunLoop
    if (currentMode->_observerMask & kCFRunLoopEntry ) 
        __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);

    // 运行RunLoop
    result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);

    // 判断是否要退出runloop,并通知观察者Observer,即将退出RunLoop
    if (currentMode->_observerMask & kCFRunLoopExit ) 
        __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);

    __CFRunLoopModeUnlock(currentMode);
    __CFRunLoopPopPerRunData(rl, previousPerRun);
    rl->_currentMode = previousMode;
    __CFRunLoopUnlock(rl);
    return result;
}

/* rl, rlm are locked on entrance and exit 
   rl: runloop 
   rlm: runloop mode 
   seconds: 超时时间
   stopAfterHandle: 完成后是否停止 runloop
   previousMode: 前一次的 mode (主要因为 runloop 可以嵌套调用)
*/
static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {
    // 当前内核时间
    uint64_t startTSR = mach_absolute_time();

    // 判断本次 runloop 或 mode 状态是否已经停止了
    if (__CFRunLoopIsStopped(rl)) {
        __CFRunLoopUnsetStopped(rl);
        return kCFRunLoopRunStopped;
    } else if (rlm->_stopped) {
        rlm->_stopped = false;
        return kCFRunLoopRunStopped;
    }
    
    // 主线程消息端口
    mach_port_name_t dispatchPort = MACH_PORT_NULL;
    // 是否在主线程中
    Boolean libdispatchQSafe = pthread_main_np() && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL == previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 == _CFGetTSD(__CFTSDKeyIsInGCDMainQ)));
    // 在主线程中 && 是主线程的runloop && mode类型为common
    if (libdispatchQSafe && (CFRunLoopGetMain() == rl) && CFSetContainsValue(rl->_commonModes, rlm->_name)) 
        // 获取GCD端口(4CF 表示 for Core Foundation)
        dispatchPort = _dispatch_get_main_queue_port_4CF();
    
// 是否使用了GCD timer
#if USE_DISPATCH_SOURCE_FOR_TIMERS
    // GCD timer 消息端口
    mach_port_name_t modeQueuePort = MACH_PORT_NULL;
    if (rlm->_queue) {
        modeQueuePort = _dispatch_runloop_root_queue_get_port_4CF(rlm->_queue);
        if (!modeQueuePort) {
            CRASH("Unable to get port for run loop mode queue (%d)", -1);
        }
    }
#endif
    
    // 超时定时器
    dispatch_source_t timeout_timer = NULL;
    // 超时定时器的上下文
    struct __timeout_context *timeout_context = (struct __timeout_context *)malloc(sizeof(*timeout_context));
    if (seconds <= 0.0) { 
        // 如果超时时间<=0.0,立即就超时了,此时不需要定时器了
        seconds = 0.0;
        timeout_context->termTSR = 0ULL;
    } else if (seconds <= TIMER_INTERVAL_LIMIT) {
        // 如果超时时间在计时器的最大计时范围内,则初始化一个计时器并开始计时
        dispatch_queue_t queue = pthread_main_np() ? __CFDispatchQueueGetGenericMatchingMain() : __CFDispatchQueueGetGenericBackground();
        // 初始化计时器
        timeout_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        dispatch_retain(timeout_timer);
        // 将计时器保存到上下文中
        timeout_context->ds = timeout_timer;
        timeout_context->rl = (CFRunLoopRef)CFRetain(rl);
        timeout_context->termTSR = startTSR + __CFTimeIntervalToTSR(seconds);
        // 设置GCD的计时器上下文为当前超时计时器的上下文
        dispatch_set_context(timeout_timer, timeout_context); 
        // 设置超时source
        dispatch_source_set_event_handler_f(timeout_timer, __CFRunLoopTimeout);
        // 设置超时取消source
        dispatch_source_set_cancel_handler_f(timeout_timer, __CFRunLoopTimeoutCancel);
        // 设置超时时间
        uint64_t ns_at = (uint64_t)((__CFTSRToTimeInterval(startTSR) + seconds) * 1000000000ULL);
        dispatch_source_set_timer(timeout_timer, dispatch_time(1, ns_at), DISPATCH_TIME_FOREVER, 1000ULL);
        // 开始计时
        dispatch_resume(timeout_timer);
    } else { 
        // 如果超时时间很大,则认为是无限时间,即永远也不可能超时(这里的seconds值大概相当于317年)
        seconds = 9999999999.0;
        timeout_context->termTSR = UINT64_MAX;
    }

    Boolean didDispatchPortLastTime = true;
    // 函数的返回值 (return value),默认为0
    int32_t retVal = 0;
    // do {} while() 这个循环就是runloop的核心代码块
    do {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        voucher_mach_msg_state_t voucherState = VOUCHER_MACH_MSG_STATE_UNCHANGED;
        voucher_t voucherCopy = NULL;
#endif  
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        mach_msg_header_t *msg = NULL;
        mach_port_t livePort = MACH_PORT_NULL;
#elif DEPLOYMENT_TARGET_WINDOWS
        HANDLE livePort = NULL;
        Boolean windowsMessageReceived = false;
#endif
        // 申请一个存放消息的空间
        uint8_t msg_buffer[3 * 1024];

        __CFPortSet waitSet = rlm->_portSet;

        __CFRunLoopUnsetIgnoreWakeUps(rl);

        // 1.通知 observer,即将处理 timers
        if (rlm->_observerMask & kCFRunLoopBeforeTimers) 
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
        // 2.通知 observer,即将处理 sources
        if (rlm->_observerMask & kCFRunLoopBeforeSources) 
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);
        
        // 3.处理 blocks
        __CFRunLoopDoBlocks(rl, rlm);

        // 4.处理 sources0
        Boolean sourceHandledThisLoop = __CFRunLoopDoSources0(rl, rlm, stopAfterHandle);
        // 如果实际处理了 sources0,则再一次处理 blocks
        if (sourceHandledThisLoop) {
            __CFRunLoopDoBlocks(rl, rlm);
        }
        
        // 处理完 sources0 或 超时时间为0
        Boolean poll = sourceHandledThisLoop || (0ULL == timeout_context->termTSR);
      
        // 5.处理主线程中的GCD事件,循环的第一次是不会进入的,因为didDispatchPortLastTime永远是true
        if (MACH_PORT_NULL != dispatchPort && !didDispatchPortLastTime) {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
            msg = (mach_msg_header_t *)msg_buffer;
            if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0, &voucherState, NULL)) {
                goto handle_msg;
            }
#elif DEPLOYMENT_TARGET_WINDOWS
            if (__CFRunLoopWaitForMultipleObjects(NULL, &dispatchPort, 0, 0, &livePort, NULL)) {
                goto handle_msg;
            }
#endif
        }
        didDispatchPortLastTime = false;

        // 6.没有处理完sources0 && 没有超时,通知 observer,即将进入睡眠
        if (!poll && (rlm->_observerMask & kCFRunLoopBeforeWaiting))    
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting);
        // 7.设置标志,正在睡眠 (实际runloop还没有睡眠)
        __CFRunLoopSetSleeping(rl);
        // 8.将GCD端口加入所有监听端口集合中
        __CFPortSetInsert(dispatchPort, waitSet);
        
        __CFRunLoopModeUnlock(rlm);
        __CFRunLoopUnlock(rl);

        // 记录睡眠开始时间
        CFAbsoluteTime sleepStart = poll ? 0.0 : CFAbsoluteTimeGetCurrent();

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
#if USE_DISPATCH_SOURCE_FOR_TIMERS
        // 如果使用 GCD timer,获取消息后需要对GCD Timer做一些额外的处理
        do {        
            if (kCFUseCollectableAllocator) {
                memset(msg_buffer, 0, sizeof(msg_buffer));
            }
            msg = (mach_msg_header_t *)msg_buffer;
            
            __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy);
            
            if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) {
                while (_dispatch_runloop_root_queue_perform_4CF(rlm->_queue));
                if (rlm->_timerFired) {
                    rlm->_timerFired = false;
                    break;
                } else {
                    if (msg && msg != (mach_msg_header_t *)msg_buffer) free(msg);
                }
            } else {
                break;
            }
        } while (1);
#else
        if (kCFUseCollectableAllocator) {
            memset(msg_buffer, 0, sizeof(msg_buffer));
        }
        msg = (mach_msg_header_t *)msg_buffer;
        __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy);
#endif
        
#elif DEPLOYMENT_TARGET_WINDOWS
        __CFRunLoopWaitForMultipleObjects(waitSet, NULL, poll ? 0 : TIMEOUT_INFINITY, rlm->_msgQMask, &livePort, &windowsMessageReceived);
#endif
        
        __CFRunLoopLock(rl);
        __CFRunLoopModeLock(rlm);

        rl->_sleepTime += (poll ? 0.0 : (CFAbsoluteTimeGetCurrent() - sleepStart));

        // 移除 GCD 端口
        __CFPortSetRemove(dispatchPort, waitSet);
        
        __CFRunLoopSetIgnoreWakeUps(rl);

        //  处理完成 GCD 后,通知 observer,即将进入睡眠
        __CFRunLoopUnsetSleeping(rl);
        if (!poll && (rlm->_observerMask & kCFRunLoopAfterWaiting)) 
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);

        // 收到消息的标签
        // 1. 基于 port 的 Sources1 的事件
        // 2. Timer 到时间
        // 3. RunLoop 超时
        // 4. 被手动唤醒
        handle_msg:;
        __CFRunLoopSetIgnoreWakeUps(rl);

#if DEPLOYMENT_TARGET_WINDOWS
        if (windowsMessageReceived) {
            __CFRunLoopModeUnlock(rlm);
            __CFRunLoopUnlock(rl);

            if (rlm->_msgPump) {
                rlm->_msgPump();
            } else {
                MSG msg;
                if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
            
            __CFRunLoopLock(rl);
            __CFRunLoopModeLock(rlm);
            sourceHandledThisLoop = true;
            
            __CFRunLoopSetSleeping(rl);
            __CFRunLoopModeUnlock(rlm);
            __CFRunLoopUnlock(rl);
            
            __CFRunLoopWaitForMultipleObjects(waitSet, NULL, 0, 0, &livePort, NULL);
            
            __CFRunLoopLock(rl);
            __CFRunLoopModeLock(rlm);            
            __CFRunLoopUnsetSleeping(rl);
        }  
#endif

        if (MACH_PORT_NULL == livePort) {
            // 不知道哪个端口唤醒的
            CFRUNLOOP_WAKEUP_FOR_NOTHING();
        } else if (livePort == rl->_wakeUpPort) {
            // 被 CFRunLoopWakeUp 函数唤醒的
            CFRUNLOOP_WAKEUP_FOR_WAKEUP();
        }

#if USE_DISPATCH_SOURCE_FOR_TIMERS
        else if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) {
            // 被 GCD timers 唤醒,处理 timers
            CFRUNLOOP_WAKEUP_FOR_TIMER();
            if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) {
                __CFArmNextTimerInMode(rlm, rl);
            }
        }
#endif

#if USE_MK_TIMER_TOO
        else if (rlm->_timerPort != MACH_PORT_NULL && livePort == rlm->_timerPort) {
            // 被其它 timers 唤醒,处理 timers
            CFRUNLOOP_WAKEUP_FOR_TIMER();
            if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) {
                __CFArmNextTimerInMode(rlm, rl);
            }
        }
#endif
        else if (livePort == dispatchPort) {
            // 被主线程 GCD 唤醒,处理 GCD
            CFRUNLOOP_WAKEUP_FOR_DISPATCH();
            __CFRunLoopModeUnlock(rlm);
            __CFRunLoopUnlock(rl);
            _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)6, NULL);
#if DEPLOYMENT_TARGET_WINDOWS
            void *msg = 0;
#endif
            __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
            _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)0, NULL);
            __CFRunLoopLock(rl);
            __CFRunLoopModeLock(rlm);
            sourceHandledThisLoop = true;
            didDispatchPortLastTime = true;
        } else {
            // 被 sources1 唤醒,处理 sources1
            CFRUNLOOP_WAKEUP_FOR_SOURCE();
            voucher_t previousVoucher = _CFSetTSD(__CFTSDKeyMachMessageHasVoucher, (void *)voucherCopy, os_release);

            CFRunLoopSourceRef rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort);
            if (rls) {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                mach_msg_header_t *reply = NULL;
                sourceHandledThisLoop = __CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply) || sourceHandledThisLoop;
                if (NULL != reply) {
                    (void)mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
                    CFAllocatorDeallocate(kCFAllocatorSystemDefault, reply);
                }
#elif DEPLOYMENT_TARGET_WINDOWS
                sourceHandledThisLoop = __CFRunLoopDoSource1(rl, rlm, rls) || sourceHandledThisLoop;
#endif
            }
            _CFSetTSD(__CFTSDKeyMachMessageHasVoucher, previousVoucher, os_release);
        } 
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        if (msg && msg != (mach_msg_header_t *)msg_buffer) free(msg);
#endif

        // 再一次处理 blocks
        __CFRunLoopDoBlocks(rl, rlm);
         
        // 判断是否退出
        if (sourceHandledThisLoop && stopAfterHandle) {
            // 处理完事件后退出
            retVal = kCFRunLoopRunHandledSource;
        } else if (timeout_context->termTSR < mach_absolute_time()) {
            // 超时退出
            retVal = kCFRunLoopRunTimedOut;
        } else if (__CFRunLoopIsStopped(rl)) {
            // 调用CFRunLoopStop()退出
            __CFRunLoopUnsetStopped(rl);
            retVal = kCFRunLoopRunStopped;
        } else if (rlm->_stopped) {
            // 运行模式被终止时退出
            rlm->_stopped = false;
            retVal = kCFRunLoopRunStopped;
        } else if (__CFRunLoopModeIsEmpty(rl, rlm, previousMode)) {
            // 没有要处理的事件时退出
            retVal = kCFRunLoopRunFinished;
        }
        
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        voucher_mach_msg_revert(voucherState);
        os_release(voucherCopy);
#endif

    } while (0 == retVal);

    if (timeout_timer) {
        dispatch_source_cancel(timeout_timer);
        dispatch_release(timeout_timer);
    } else {
        free(timeout_context);
    }

    return retVal;
}

Runloop 运行的核心函数__CFRunLoopRun大概有300多行代码,看似很多代码,其实其中有很多是为了适配不同平台的代码,如果我们将其删减一下,删掉那些平台的适配以及一些复杂的逻辑判断,我们就可以得到如下的runloop执行过程

staticint32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {
    do {
        // 1. 通知 observers,RunLoop 即将处理 Timers
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
        // 2. 通知 observers,RunLoop 即将处理 Sources
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);
        // 3. 处理 sources0 事件
        __CFRunLoopDoSources0(rl, rlm, stopAfterHandle);
        // 4. 处理 blocks
        __CFRunLoopDoBlocks(rl, rlm);
        // 5. 处理 sources1 事件
        goto handle_msg;
        // 6. 通知 observers, RunLoop 即将休眠
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting);
        // 7. RunLoop 休眠
        __CFRunLoopSetSleeping(rl);
        // 8. 线程进入休眠, 直到被下面某一个事件唤醒:
        // a. 基于 port 的 Source1 的事件
        // b. Timer 到时间了
        // c. RunLoop 启动时设置的最大超时时间到了
        // d. 被手动唤醒
        // 9. 当接收到第8步中的消息时,Runloop 醒来
        __CFRunLoopUnsetSleeping(rl);
        // 10. 通知 observers,RunLoop 已被唤醒
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);
        // 11. 处理消息
        handle_msg:;
        if(MACH_PORT_NULL == livePort) {
            CFRUNLOOP_WAKEUP_FOR_NOTHING();
        } else if(livePort == rl->_wakeUpPort) {
            CFRUNLOOP_WAKEUP_FOR_WAKEUP();
        } else if(modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) {
            // 处理定时器事件
            CFRUNLOOP_WAKEUP_FOR_TIMER();
        } else if(livePort == dispatchPort) {
            // 处理主线程消息
            CFRUNLOOP_WAKEUP_FOR_DISPATCH();
        } else {
            // 处理 sources1
            CFRUNLOOP_WAKEUP_FOR_SOURCE();
        } 
        // 12. 退出 RunLoop
    return retVal;
}
上一篇下一篇

猜你喜欢

热点阅读