一、什么是Runloop?为什么需要Runloop?
Runloop,顾名思义,即运行循环。
没有Runloop的情况下,一个线程执行完一个任务,就会退出并销毁。等到需要处理下一个任务时,再重新创建一个线程。
1、当任务小而多时,频繁地创建和销毁线程,会带来不小的代价。
2、主线程要是退出了,整个iOS/OSX应用就挂了。
因此,需要一种能让线程不退出、有任务时可以及时处理、没任务时又可以不占用CPU的机制。这种机制就是event loop,Runloop是event loop在iOS/OSX中的实现。
二、Runloop的实现
Runloop提供了两种API,一种是Foundation中Objective-C实现的NSRunloop;另一种是CoreFoundation中纯C实现的CFRunloopRef,NSRunloop是对CFRunloopRef的封装。
官方文档给出的主要流程:
对应的主要源码:
__CFRunLoopDoObservers(kCFRunLoopEntry); // 1、通知Observer,进入Runloop do { // Runloop的一次迭代 __CFRunLoopDoObservers(kCFRunLoopBeforeTimers); // 2、通知Observer,即将处理timer __CFRunLoopDoObservers(kCFRunLoopBeforeSources); // 3、通知Observer,即将处理source __CFRunLoopDoSources0(); // 4、处理source0 __CFRunLoopServiceMachPort(); // 5、 __CFRunLoopDoObservers(kCFRunLoopBeforeWaiting); // 6、通知Observer,即将休眠等待 __CFRunLoopSetSleeping(); // 7、休眠等待 __CFRunLoopDoObservers(kCFRunLoopAfterWaiting); // 8、通知Observer,即将被唤醒 __CFRunLoopDoTimers() // 9.1、处理timer __CFRunLoopDoSource1(); // 9.2、处理source1 } while; __CFRunLoopDoObservers(kCFRunLoopExit); // 10、通知Observer,结束Runloop
mach_msg:从目标端口发送或者接收消息的系统调用。
mach port
MACH_SEND_MSG
MACH_RCV_MSG
消息队列
基于port的source1事件
mach_msg_trap
performSelector
main queue
三、Runloop Mode
四、Runloop的应用
1、AutoreleasePool
2、AFNetworking
五、Mach进程间通信
参考链接:
https://opensource.apple.com/source/CF/CF-635.19/CFRunLoop.c.auto.html
http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_msg.html