一较雕、相關(guān)概念:
- 首先,RunLoop是iOS/OS X開(kāi)發(fā)中非持勘遥基礎(chǔ)的一個(gè)概念亮蒋,我們先來(lái)看一下有關(guān)它的概念和實(shí)現(xiàn)方法:
正常來(lái)說(shuō),一個(gè)線程一般只能執(zhí)行一個(gè)任務(wù)妆毕,執(zhí)行完成后線程就會(huì)退出∩骶粒現(xiàn)在我們需要一個(gè)機(jī)制,讓線程能隨時(shí)處理事件但不退出笛粘,一般邏輯代碼是這樣的:
function loop() {
initialize();
do {
var message = get_next_message();
process_message(message);
} while (message != quit);
}
- kCFRunLoopDefaultMode: App的默認(rèn) Mode趁怔,通常主線程是在這個(gè) Mode 下運(yùn)行的湿硝。
- UITrackingRunLoopMode: 界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動(dòng)润努,保證界面滑動(dòng)時(shí)不受其他 Mode 影響关斜。
- UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode,啟動(dòng)完成后就不再使用任连。
- GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode蚤吹,通常用不到。
5.NSRunLoopCommonModes: 包含 1 和 2 一般來(lái)說(shuō)包含 UITrackingRunLoopMode 和 NSDefaultRunLoopMode
二随抠、RunLoop的實(shí)現(xiàn)
// 底層的實(shí)現(xiàn)函數(shù)
SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled){
// 配置RunLoop的Mode
SetupCFRunLoopMode()
// 通知 Observers 將要進(jìn)入 Loop
__CFRunLoopDoObservers(kCFRunLoopEntry);
// 通過(guò)GCD設(shè)置RunLoop的超時(shí)時(shí)間
SetupThisRunLoopRunTimeoutTimer();
// RunLoop開(kāi)始處理事件 do while 循環(huán)
do {
// 通知 Observers 將執(zhí)行timer
__CFRunLoopDoObservers(kCFRunLoopBeforeTimers);
// 通知 Observers 將執(zhí)行Source0
__CFRunLoopDoObservers(kCFRunLoopBeforeSources);
// 執(zhí)行blocks
__CFRunLoopDoBlocks();
// 執(zhí)行Source0
__CFRunLoopDoSource0();
// 問(wèn) GCD 主線程有沒(méi)有需要執(zhí)行的東西
CheckIfExistMessagesInMainDispatchQueue();
// 通知 Observers 將進(jìn)入睡眠
__CFRunLoopDoObservers(kCFRunLoopBeforeWaiting);
/* 指定 喚醒端口
監(jiān)聽(tīng) mach_msg 會(huì)停在這里
進(jìn)入 mach_msg_trap 狀態(tài)
睡眠中...
*/
var wakeUpPort = SleepAndWaitForWakingUpPorts();
// 接收到 消息 通知Observers RunLoop被喚醒了
__CFRunLoopDoObservers(kCFRunLoopAfterWaiting);
// 處理事件
if (wakeUpPort == timerPort) {
// 喚醒端口是 timerPort 執(zhí)行timer回調(diào) /* DOES CALLOUT */
__CFRunLoopDoTimers();
} else if (wakeUpPort == mainDispatchQueuePort) {
// 喚醒端口 執(zhí)行mainQueue里面的調(diào)用
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__()
} else {
// 喚醒端口 執(zhí)行Source1回調(diào)
__CFRunLoopDoSource1();
}
// 執(zhí)行 blocks
__CFRunLoopDoBlocks()裁着;
// 當(dāng)事件處理完了、被強(qiáng)制停止了拱她、超時(shí)了二驰、Mode是空的時(shí)候就會(huì)退出 循環(huán)
} while (!stop && isStopped !timeout && !ModeIsEmpty );
// 通知 Observers 將退出Loop
__CFRunLoopDoObservers(kCFRunLoopExit);
}
說(shuō)明:本文章僅供學(xué)習(xí)交流使用