定义
- RunLoop本质上是一个do-while循环
RunLoop状态
- kCFRunLoopEntry
- kCFRunLoopBeforeTimers
- kCFRunLoopBeforeSources
- kCFRunLoopBeforeWaiting
- kCFRunLoopAfterWaiting
- kCFRunLoopExit
底层源码分析
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) { /* DOES CALLOUT */
//通知Observer 进入kCFRunLoopEntry状态 【进入】
if (currentMode->_observerMask & kCFRunLoopEntry ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);
result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);
//通知Observer 进入kCFRunLoopExit状态 【退出】
if (currentMode->_observerMask & kCFRunLoopExit ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
return result;
}
static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {
int32_t retVal = 0;
do {
//通知observer 进入kCFRunLoopBeforeTimers 处理timers
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
//通知observer kCFRunLoopBeforeSources 处理source
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);
//处理blocks
__CFRunLoopDoBlocks(rl, rlm);
//处理sources0
__CFRunLoopDoSources0(rl, rlm, stopAfterHandle);
//处理完sources0,再次处理Blocks
__CFRunLoopDoBlocks(rl, rlm);
//判断是否有source1 Port
if (MACH_PORT_NULL != dispatchPort && !didDispatchPortLastTime) {
msg = (mach_msg_header_t *)msg_buffer;
if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0, &voucherState, NULL)) {
//如果有 goto:handle_msg
goto handle_msg;
}
}
//通知observer,进入kCFRunLoopBeforeWaiting状态
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting);
//开始睡眠
__CFRunLoopSetSleeping(rl);
//等待别的消息来唤醒当前线程
do {
__CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy);
} while (1);
//通知observer,结束休眠
__CFRunLoopUnsetSleeping(rl);
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);
handle_msg:
//被timer唤醒
if (WAKEUP_FOR_TIMER) {
CFRUNLOOP_WAKEUP_FOR_TIMER();
//处理timers
__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())
//被GCD唤醒
}else if (WAKEUP_FOR_DISPATCH) {
//处理GCD
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
//被SOURCE1唤醒
} else WAKEUP_FOR_SOURCE {
//处理Source1
__CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply)
}
//处理Block
__CFRunLoopDoBlocks(rl, rlm);
//设置retVal的状态
if (sourceHandledThisLoop && stopAfterHandle) {
retVal = kCFRunLoopRunHandledSource;
} else if (timeout_context->termTSR < mach_absolute_time()) {
//超时
retVal = kCFRunLoopRunTimedOut;
} else if (__CFRunLoopIsStopped(rl)) {
//被手动终止
__CFRunLoopUnsetStopped(rl);
retVal = kCFRunLoopRunStopped;
} else if (rlm->_stopped) {
rlm->_stopped = false;
retVal = kCFRunLoopRunStopped;
} else if (__CFRunLoopModeIsEmpty(rl, rlm, previousMode)) {
//没有Source、Timers、observers
retVal = kCFRunLoopRunFinished;
}
} while (0 == retVal);
return retVal;
}
总结
RunLoop的内部执行逻辑:
- 通知Observer 进入kCFRunLoopEntry状态 【进入】
- 通知Observer 进入kCFRunLoopBeforeTimers 【处理timers】
- 通知Observer 进入kCFRunLoopBeforeSources【处理source】
- 处理blocks
- 处理sources0
- 处理完sources0,再次处理Blocks
- 如果有source1 进入进入9
- 通知observer,进入kCFRunLoopBeforeWaiting状态 【开始休眠】
- 通知observer,进入kCFRunLoopAfterWaiting状态 【结束休眠】
- 处理Timers
- 处理GCD
- 处理Source1
- 通知Observer 进入kCFRunLoopExit状态 【退出】