首页 > 其他 > 详细

RunLoop

时间:2016-03-07 11:45:32      阅读:278      评论:0      收藏:0      [点我收藏+]

参考资料:

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的种类有: 

  • NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
  • UITrackingRunLoopMode:使用这个Mode去跟踪来自用户交互的事件,比如 ScrollView滑动时。
  • UIInitializationRunLoopMode:启动时
  • NSRunLoopCommonModes(kCFRunLoopCommonModes):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的几个场景:

  • 需要使用Port-Based Input Source或者Custom Input Source和其他线程通讯时
  • 需要在线程中使用Timer
  • 需要在线程中使用上文提到的selector相关方法(Cocoa框架为我们定义了一些Custom Input Sources,允许我们在线程中执行一系列selector方法)
  • 需要让线程执行周期性的工作

 后续:

1)程序深入验证:NSTimer, NSURLConnection和NSStream默认运行在Default Mode下,UIScrollView在接收到用户交互事件时,主线程Run Loop会设置为UITrackingRunLoopMode下,这个时候NSTimer不能fire,NSURLConnection的数据也无法处理。 

RunLoop

原文:http://www.cnblogs.com/Xylophone/p/5237984.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!