Objective-C Runloop深入理解
通常情況下,一個線程執行完一個任務,就會退出並銷毀。等到需要處理下一個任務時,又得重新創建一個線程。但是很多時候,這並不是我們想要的結果。例如,
1、當任務小而多時,頻繁地創建和銷毀線程,會帶來不小的代價。
2、iOS/OSX應用的主線程要是退出了,整個應用就掛了。
因此,需要一種能讓線程不退出的機制。這種機制就是event loop,event loop在很多語言中都有。Runloop就是它在Objective-C中的實現。
Runloop其實就是個do while循環。它能讓線程在沒有任務時休眠等待,以避免占用CPU,而有任務需要處理時,又可以及時喚醒。這是怎麽做到的呢?需要從Runloop的實現中一探究竟。
Runloop提供了兩種API,一種是CoreFoundation中純C實現的CFRunloopRef;另一種是Foundation中的Objective-C實現的NSRunloop,NSRunloop是對CFRunloopRef的封裝。秘密就隱藏在CFRunloopRef的源碼中。
void CFRunLoopRun() {
CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false); }
SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) { __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);// 1、通知Observer,進入Runloop __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode); __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit); // 10、通知Observer,結束Runloop }
static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) { int32_t retVal= 0; do { // Runloop的一次叠代 __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers); // 2、通知Observer,即將處理timer __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources); // 3、通知Observer,即將處理source __CFRunLoopDoBlocks(rl, rlm); // 執行block __CFRunLoopDoSources0(rl, rlm, stopAfterHandle); // 處理source0 __CFRunLoopDoBlocks(rl, rlm); // 執行block __CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0)); // 處理source1 __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting); // 6、通知Observer,即將休眠等待 __CFRunLoopSetSleeping(rl); // 7、休眠等待 __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting); // 8、通知Observer,即將被喚醒 __CFRunLoopDoTimers(rl, rlm, mach_absolute_time()) // 處理timer __CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply); // 處理source1 __CFRunLoopDoBlocks(rl, rlm); // 執行block } while (0 == retVal); return retVal; }
參考鏈接:
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW23
http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_msg.html
==========================================
mach_msg
MACH_SEND_MSG
MACH_RCV_MSG
Objective-C Runloop深入理解