//RunLoop的實(shí)現(xiàn)
intCFRunLoopRunSpecific(runloop, modeName, seconds, stopAfterHandle) {
// 0.1根據(jù)modeName找到對(duì)應(yīng)mode
CFRunLoopModeRef currentMode = __CFRunLoopFindMode(runloop, modeName,false);
// 0.2如果mode里沒(méi)有source/timer直接返回。
if(__CFRunLoopModeIsEmpty(currentMode))return;
// 1.1通知Observers: RunLoop即將進(jìn)入loop。---(OB會(huì)創(chuàng)建釋放池)
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopEntry);
// 1.2內(nèi)部函數(shù)耕腾,進(jìn)入loop
__CFRunLoopRun(runloop, currentMode, seconds, returnAfterSourceHandled) {
Boolean sourceHandledThisLoop =NO;
intretVal =0;
do{
// 2.1通知Observers: RunLoop即將觸發(fā)Timer回調(diào)狗准。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeTimers);
// 2.2通知Observers: RunLoop即將觸發(fā)Source0 (非port)回調(diào)云矫。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeSources);
//執(zhí)行被加入的block
__CFRunLoopDoBlocks(runloop, currentMode);
// 2.3 RunLoop觸發(fā)Source0 (非port)回調(diào)善涨。
sourceHandledThisLoop = __CFRunLoopDoSources0(runloop, currentMode, stopAfterHandle);
//執(zhí)行被加入的block
__CFRunLoopDoBlocks(runloop, currentMode);
// 2.4如果有Source1 (基于port)處于ready狀態(tài)其骄,直接處理這個(gè)Source1然后跳轉(zhuǎn)去處理消息恐疲。
if(__Source0DidDispatchPortLastTime) {
Boolean hasMsg = __CFRunLoopServiceMachPort(dispatchPort, &msg)
if(hasMsg)gotohandle_msg;
}
// 3.1如果沒(méi)有待處理消息腊满,通知Observers: RunLoop的線程即將進(jìn)入休眠(sleep)套么。--- (OB會(huì)銷毀釋放池并建立新釋放池)
if(!sourceHandledThisLoop) {
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeWaiting);
}
// 3.2.調(diào)用mach_msg等待接受mach_port的消息。線程將進(jìn)入休眠,直到被下面某一個(gè)事件喚醒碳蛋。
/*
一個(gè)基于port的Source1的事件勺届。
一個(gè)Timer到時(shí)間了
RunLoop啟動(dòng)時(shí)設(shè)置的最大超時(shí)時(shí)間到了
被手動(dòng)喚醒
*/
__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類型欧募,觸發(fā)這個(gè)Timer的回調(diào)糜工。
if(msg_is_timer) {
__CFRunLoopDoTimers(runloop, currentMode, mach_absolute_time())
}
// 4.2如果消息是dispatch到main_queue的block颂斜,執(zhí)行block为迈。
elseif(msg_is_dispatch) {
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
}
// 4.3如果消息是Source1類型,處理這個(gè)事件
else{
CFRunLoopSourceRef source1 = __CFRunLoopModeFindSourceForMachPort(runloop, currentMode, livePort);
sourceHandledThisLoop = __CFRunLoopDoSource1(runloop, currentMode, source1, msg);
if(sourceHandledThisLoop) {
mach_msg(reply, MACH_SEND_MSG, reply);
}
}
//執(zhí)行加入到Loop的block
__CFRunLoopDoBlocks(runloop, currentMode);
// 5.1如果處理事件完畢箩兽,啟動(dòng)Runloop時(shí)設(shè)置參數(shù)為一次性執(zhí)行,設(shè)置while參數(shù)退出Runloop
if(sourceHandledThisLoop && stopAfterHandle) {
retVal = kCFRunLoopRunHandledSource;
// 5.2如果啟動(dòng)Runloop時(shí)設(shè)置的最大運(yùn)轉(zhuǎn)時(shí)間到期津肛,設(shè)置while參數(shù)退出Runloop
}elseif(timeout) {
retVal = kCFRunLoopRunTimedOut;
// 5.3如果啟動(dòng)Runloop被外部調(diào)用強(qiáng)制停止,設(shè)置while參數(shù)退出Runloop
}elseif(__CFRunLoopIsStopped(runloop)) {
retVal = kCFRunLoopRunStopped;
// 5.4如果啟動(dòng)Runloop的modeItems為空汗贫,設(shè)置while參數(shù)退出Runloop
}elseif(__CFRunLoopModeIsEmpty(runloop, currentMode)) {
retVal = kCFRunLoopRunFinished;
}
// 5.5如果沒(méi)超時(shí)身坐,mode里沒(méi)空,loop也沒(méi)被停止落包,那繼續(xù)loop部蛇,回到第2步循環(huán)。
}while(retVal ==0);
}
// 6.如果第6步判斷后loop退出咐蝇,通知Observers: RunLoop退出涯鲁。--- (OB會(huì)銷毀新釋放池)
__CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);