码迷,mamicode.com
首页 > 其他好文 > 详细

Objective-C Runloop深入理解

时间:2019-01-15 20:32:04      阅读:215      评论:0      收藏:0      [点我收藏+]

标签: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;
}

 

 

技术分享图片

 

 

 

参考链接:

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深入理解

标签:nsrunloop   width   隐藏   loop   amp   hand   timers   play   带来   

原文地址:https://www.cnblogs.com/yangwenhuan/p/9307368.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!