RunLoop入门

作者: pp_panda | 来源:发表于2015-01-04 11:40 被阅读0次

       之前在使用NSTimer时,遇到一个问题,NSTimer启动了,但是只会出现一次定时,之后就不起作用。问了同事,他说需要加在RunLoop中,我没有考虑太多,就听他说的,在外层加了一个Runloop,定时器确实起作用了。近期做另一个任务,发现RunLoop在多线程中用的比较多,所以大概查了下相关资料。

      runLoop是线程中的循环,并对收到的事件进行处理,它从两个不同的事件源中接收消息。Input sources(CFRunLoopSource)投递异步消息,通常来源于另一个thread或者另一个应用程序。Timer sources(CFRunLoopTimer)当在计划的时间或重复的时间间隔内投递同步消息。两种事件源都使用应用程序指定的处理方式对到达的事件进行处理。下图展示了run loop和不同的事件源结构:

Run Loop的使用场合:

 1. 使用port或是自定义的input source来和其他线程进行通信                                          2. 在线程(非主线程)中使用timer                                                                            3. 使用 performSelector…系列(如performSelectorOnThread, …)                          4. 使用线程执行周期性工作

run loop不需要创建,在线程中只需要调用[NSRunLoop currentRunLoop]就可以得到假设我们想要等待某个异步方法的回调。比如connection。如果我们的线程中没有启动run loop,是不会有效果的(因为线程已经运行完毕,正常退出了)。                                  使用runLoop阻塞线程的正确写法                                                        @implementation ViewController                                                                              {                                                                                                                                      BOOL end;                                                                                                          }

– (void)viewDidLoad                                                                                                 {                                                                                                                                      [super viewDidLoad];                                                                                                NSLog(@”start new thread …”);                                                                                  [NSThread detachNewThreadSelector:@selector(runOnNewThread)                          toTarget:self withObject:nil];                                                                                    while (!end) {                                                                                                            NSLog(@”runloop…”);                                                                                                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:         [NSDate distantFuture]];                                                                                           NSLog(@”runloop end.”);                                                                                           }                                                                                                                               NSLog(@”ok.”);                                                                                                   }

-(void)runOnNewThread                                                                                          {                                                                                                                                     NSLog(@”run for new thread …”);                                                                             sleep(1);                                                                                                                   [self performSelectorOnMainThread:@selector(setEnd) withObject:nil                       waitUntilDone:NO];                                                                                                 NSLog(@”end.”);                                                                                                 }

-(void)setEnd  {                                                                                                               end=YES;                                                                                                           }

每次运行 Run loop,你线程的 Run loop 对会自动处理之前未处理的消息,并通知相关的观察者。具体的顺序如下:

1. 通知观察者 Run loop 已经启动。

2. 通知观察者任何即将要开始的定时器。

3. 通知观察者任何即将启动的非基于端口的源。

4. 启动任何准备好的非基于端口的源。

5. 如果基于端口的源准备好并处于等待状态,立即启动;并进入步骤 9。

6. 通知观察者线程进入休眠。

7. 将线程置于休眠直到任一下面的事件发生:

   某一事件到达基于端口的源;

   定时器启动;

   Run loop 设置的时间已经超时;

   Run loop 被显式唤醒。

8. 通知观察者线程将被唤醒。

9. 处理未处理的事件

    如果用户定义的定时器启动,处理定时器事件并重启 Run loop。进入步骤 2。

    如果输入源启动,传递相应的消息。

    如果 Run loop 被显式唤醒而且时间还没超时,重启 Run loop,进入步骤 2。

10. 通知观察者 Run loop 结束。

相关文章

  • RunLoop汇总

    RunLoop 入门 看我就够了RunLoop 已入门?不来应用一下?ibireme的文章,关于RunLoop背后...

  • 底层原理探究(二)RunLoop

    转自: 老司机出品——源码解析之RunLoop详解入门使用: RunLoop入门 看我就够了孙源的Runloop视...

  • iOS复习之RunLoop

    1、事件循环2、用户态3、核心态4、常驻线程 主要 RunLoop文章:RunLoop入门 看我就够了iOS - ...

  • RunLoop入门

    什么是RunLoop Run Loop是一让线程能随时处理事件但不退出的机制。RunLoop 实际上是一个对象,这...

  • RunLoop入门

    我们的项目其实就是一个RunLoop,比如main函数的UIApplicationMain就是一个死循环函数,它在...

  • RunLoop入门

    之前在使用NSTimer时,遇到一个问题,NSTimer启动了,但是只会出现一次定时,之后就不起作用。问了同...

  • RunLoop入门学习补充资料

    本文是对iOS RunLoop入门小结一文的资料补充 1.RunLoop运行逻辑 以下是伪代码1,摘自https:...

  • RunLoop入门提高

    RunLoop是iOS和OSX开发中非常基础的一个概念.首先从CFRunLoop的源码入手,介绍RunLoop的概...

  • RunLoop已入门?不来应用一下?

    前言 对RunLoop还没有什么概念的同学请移步我的上一篇文章,传送门:RunLoop入门 看我就够了http:/...

  • RunLoop已入门?不来应用一下?

    前言 对RunLoop还没有什么概念的同学请移步我的上一篇文章,传送门:RunLoop入门 看我就够了 http:...

网友评论

    本文标题:RunLoop入门

    本文链接:https://www.haomeiwen.com/subject/keaztttx.html