//RunLoop的实现
intCFRunLoopRunSpecific(runloop, modeName, seconds, stopAfterHandle) {
// 0.1根据modeName找到对应mode
CFRunLoopModeRef currentMode = __CFRunLoopFindMode(runloop, modeName,false);
// 0.2如果mode里没有source/timer直接返回。
if(__CFRunLoopModeIsEmpty(currentMode))return;
// 1.1通知Observers: RunLoop即将进入loop。---(OB会创建释放池)
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopEntry);
// 1.2内部函数,进入loop
__CFRunLoopRun(runloop, currentMode, seconds, returnAfterSourceHandled) {
Boolean sourceHandledThisLoop =NO;
intretVal =0;
do{
// 2.1通知Observers: RunLoop即将触发Timer回调。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeTimers);
// 2.2通知Observers: RunLoop即将触发Source0 (非port)回调。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeSources);
//执行被加入的block
__CFRunLoopDoBlocks(runloop, currentMode);
// 2.3 RunLoop触发Source0 (非port)回调。
sourceHandledThisLoop = __CFRunLoopDoSources0(runloop, currentMode, stopAfterHandle);
//执行被加入的block
__CFRunLoopDoBlocks(runloop, currentMode);
// 2.4如果有Source1 (基于port)处于ready状态,直接处理这个Source1然后跳转去处理消息。
if(__Source0DidDispatchPortLastTime) {
Boolean hasMsg = __CFRunLoopServiceMachPort(dispatchPort, &msg)
if(hasMsg)gotohandle_msg;
}
// 3.1如果没有待处理消息,通知Observers: RunLoop的线程即将进入休眠(sleep)。--- (OB会销毁释放池并建立新释放池)
if(!sourceHandledThisLoop) {
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeWaiting);
}
// 3.2.调用mach_msg等待接受mach_port的消息。线程将进入休眠,直到被下面某一个事件唤醒。
/*
一个基于port的Source1的事件。
一个Timer到时间了
RunLoop启动时设置的最大超时时间到了
被手动唤醒
*/
__CFRunLoopServiceMachPort(waitSet, &msg,sizeof(msg_buffer), &livePort) {
mach_msg(msg, MACH_RCV_MSG, port);// thread wait for receive msg
}
// 3.3.被唤醒,通知Observers: RunLoop的线程刚刚被唤醒了。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopAfterWaiting);
// 4.0处理消息。
handle_msg:
// 4.1如果消息是Timer类型,触发这个Timer的回调。
if(msg_is_timer) {
__CFRunLoopDoTimers(runloop, currentMode, mach_absolute_time())
}
// 4.2如果消息是dispatch到main_queue的block,执行block。
elseif(msg_is_dispatch) {
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
}
// 4.3如果消息是Source1类型,处理这个事件
else{
CFRunLoopSourceRef source1 = __CFRunLoopModeFindSourceForMachPort(runloop, currentMode, livePort);
sourceHandledThisLoop = __CFRunLoopDoSource1(runloop, currentMode, source1, msg);
if(sourceHandledThisLoop) {
mach_msg(reply, MACH_SEND_MSG, reply);
}
}
//执行加入到Loop的block
__CFRunLoopDoBlocks(runloop, currentMode);
// 5.1如果处理事件完毕,启动Runloop时设置参数为一次性执行,设置while参数退出Runloop
if(sourceHandledThisLoop && stopAfterHandle) {
retVal = kCFRunLoopRunHandledSource;
// 5.2如果启动Runloop时设置的最大运转时间到期,设置while参数退出Runloop
}elseif(timeout) {
retVal = kCFRunLoopRunTimedOut;
// 5.3如果启动Runloop被外部调用强制停止,设置while参数退出Runloop
}elseif(__CFRunLoopIsStopped(runloop)) {
retVal = kCFRunLoopRunStopped;
// 5.4如果启动Runloop的modeItems为空,设置while参数退出Runloop
}elseif(__CFRunLoopModeIsEmpty(runloop, currentMode)) {
retVal = kCFRunLoopRunFinished;
}
// 5.5如果没超时,mode里没空,loop也没被停止,那继续loop,回到第2步循环。
}while(retVal ==0);
}
// 6.如果第6步判断后loop退出,通知Observers: RunLoop退出。--- (OB会销毁新释放池)
__CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);