标签:nsrunloop width 隐藏 loop amp hand timers play 带来
通常情况下,一个线程执行完一个任务,就会退出并销毁。等到需要处理下一个任务时,又得重新创建一个线程。但是很多时候,这并不是我们想要的结果。例如,
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; }
参考链接:
http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_msg.html
==========================================
mach_msg
MACH_SEND_MSG
MACH_RCV_MSG
标签:nsrunloop width 隐藏 loop amp hand timers play 带来
原文地址:https://www.cnblogs.com/yangwenhuan/p/9307368.html