参考资料:
http://chun.tips/blog/2014/10/20/zou-jin-run-loopde-shi-jie-%5B%3F%5D-:shi-yao-shi-run-loop%3F/ ;
http://blog.ibireme.com/2015/05/18/runloop/ ;
1. RunLoop的本质:线程中的循环。
它用来接受循环中的事件和安排线程工作,并在没有工作时,让线程进入睡眠状态。
以下是Event Loop的逻辑:
function loop() { initialize(); do { var message = get_next_message(); process_message(message); } while (message != quit); }
RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行上面 Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 "接受消息->等待->处理" 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。
RunLoop和线程的关系:
线程和 Run Loop 之间是一一对应的。Run Loops是线程的基础架构部分。每个线程都有对应的Run Loop。
在任何一个Cocoa程序的线程中,都可以通过以下代码来获取到当前线程的Run Loop:
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
ios程序启动执行的main函数如下
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([CCAppDelegate class])); } }
其中,UIApplicationMain()函数会为main thread设置NSRunLoop对象,也就是说程序启动时,主线程的RunLoop对象启动,所以,我们的App可以在无人操作时休息,有人操作时立马响应。对其它线程来说,run loop默认是没有启动的。也就是说,线程刚创建时并没有 RunLoop,如果不主动获取,那它一直都不会有。RunLoop 的创建是发生在第一次获取时,RunLoop 的销毁是发生在线程结束时。只能在一个线程的内部获取其 RunLoop(主线程除外)。
2. RunLoop Mode: 一个集合(包括:所有要监视的事件源和要通知的Run Loop中注册的观察者)
Run Loop被事件源触发,然后Run Loop中注册的观察者得到通知,执行对应的函数。事件源的分类如下所示:
(https://github.com/SheronLv/Images/blob/master/RunLoop/RunLoop事件源分类.png)
其中,Port-Based sources是系统的源,Custom input sources是自定义输入源,除了可以通过CFRunLoopSourceCreate创建自定义输入源,还有一种selector源也是属于Custom input sources:
//在主线程的Run Loop下执行指定的 @selector 方法 performSelectorOnMainThread:withObject:waitUntilDone: performSelectorOnMainThread:withObject:waitUntilDone:modes: //在当前线程的Run Loop下执行指定的 @selector 方法 performSelector:onThread:withObject:waitUntilDone: performSelector:onThread:withObject:waitUntilDone:modes: //在当前线程的Run Loop下延迟加载指定的 @selector 方法 performSelector:withObject:afterDelay: performSelector:withObject:afterDelay:inModes: //取消当前线程的调用 cancelPreviousPerformRequestsWithTarget: cancelPreviousPerformRequestsWithTarget:selector:object:
RunLoop Mode的种类有:
RunLoop以一种固定的Mode运行,只会监控这个Mode下添加的Input source和Timer source,如果这个Mode下没有添加事件源,RunLoop就会立即返回。
(https://github.com/SheronLv/Images/blob/master/RunLoop/RunLoopObserver.png)
3. Run Loop的优点
(1)NSRunLoop是一种消息处理模式,它对消息处理的过程进行了封装,使App程序员不用处理一些很琐碎很低层次的具体消息的处理,在NSRunLoop中每一个消息就被打包在input source或者是timer source中了。
(2)使用run loop可以使你的线程在有工作的时候工作,没有工作的时候休眠,这可以大大节省系统资源。
4. 何时使用RunLoop?
在创建辅助线程的时候,才显式的运行一个Run Loop。对于辅助线程,我们仍然需要判断是否需要启动Run Loop。下面是官方Document提供的使用Run Loop的几个场景:
selector
相关方法(Cocoa框架为我们定义了一些Custom Input Sources,允许我们在线程中执行一系列selector
方法)后续:
1)程序深入验证:NSTimer, NSURLConnection和NSStream默认运行在Default Mode下,UIScrollView在接收到用户交互事件时,主线程Run Loop会设置为UITrackingRunLoopMode下,这个时候NSTimer不能fire,NSURLConnection的数据也无法处理。
原文:http://www.cnblogs.com/Xylophone/p/5237984.html