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

探索 Run Loop

时间:2016-05-25 16:50:18      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:

  

 说到RunLoop,无论从项目代码或者网上都会有以下这段代码:

    while (!_isFinish)

    {

        NSRunLoop *runloop = [NSRunLoop currentRunLoop];

        [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

    }

究竟[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]干啥的?

本文本最重要的是要说明白这个事情!准备好开始了.

对于single view application的应用程序,UIApplicationMain()方法在这里不仅完成了初始化我们的程序并设置程序Delegate的任务,而且随之开启了主线程的Run Loop, 开始接受处理事件。

  从简单开始,通过监听runloop状态,查看进入程序什么都不干,runloop会干点啥。

  监听代码如下:

  技术分享
  

  技术分享

  

runLoopActivityStringWithActivity函数只是简单的把值转换成对应的文本方便查看。

打印结果如下:

  技术分享

log出来CFRunLoopActivity对应着别人简化runloop源码逻辑看,本文其它log也可

以对着看。
  技术分享

可知道:程序在经过了一系列变化后进入了休眠状态。

 

然后在viewController里加入个按钮button one,响应代码如下:


  技术分享

点击后打印结果:

技术分享

 

主线程被换醒,然后处理按钮事件,接着过了一阵子就会从新进入休眠,等待下一事件。

 

继续往下,我又加了一个button two。并把代码修改成如下,大家都知道,点击了
button one 后就进入了死循环,点击button two 是不起作用的。这里就不上Log了。
技术分享

但是把button one 代码改成下面这样,就算button one代码没有执行完,同样可以
在主线程响应button two的事件。究竟

[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

做了什么事情呢?

技术分享

此时打印出来的log如下:

技术分享

从log中看到并没有打印出one button End.说明one button 还没有执行完。

但是我们可以看到one button before和after RunLoop被打印了好几次,并且CFRunLoopActivity

打印出来好几次1和128.说明RunLoop是有退出和重新进入的。不是说主线程的runLoop不会退出的吗?

难道打出来的不是主线程的runLoop?下面就慢慢说明白这些东西

为了方便理解,我会把启动时应用给我们创建的RunLoop叫做RunLoop对象,它会一直循环着简化

runloop源码的逻辑。可以这样说RunLoop对象创建了一个循环,这个循环可以在有事件发生里处理
事件,没事发生就会休眠,等待事件发生。那为什么开始没改代码时那种情况为什么响应不了button two的事件呢,那是因为处理button one事件没还返回,系统给我们创建的这个循环并不能往下走了所以处理不了button two。而修改代码后,[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]其实是为RunLoop对象创建了个新的循环。一次循环只会打有一个kCFRunLoopEntry和kCFRunLoopExit,中间的CFRunLoopActivity状态则要看情况而定,如有哪个输入源等。到达kCFRunLoopExit表明这个循环要退出。由于while中一直为true,循环会不停被启动。[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]创建的循环我叫它子循环,button two 事件其实是在这个子循环里被处理。所以RunLoop对象的循环可以有多个,并且是嵌套的。事件处理会被嵌套最深的那个子循环处理。为了证实这个说法继续加了个button three,并把button two 代码修改,代码如下

技术分享

连续点击button one two there.在three中打个断点。调用栈如下:

技术分享

 

很明显看到,button two的事件是在one中创建的子循环执行,而button three的事件是在two中创建的子

循环执行。

 

总结:

1、[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]其实是为线程创建

一个循环,如果线程已经有,创建的是一个子循环。

2、通过[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]创建的循环过一段时间或

马上返回,这取决于输入源及系统的调度。所以用while进行不断驱动,不停创建循环。

3、我们看到日志打印出kCFRunLoopExit是子循环的exit.

 

探索 Run Loop

标签:

原文地址:http://www.cnblogs.com/chenxianming/p/5527498.html

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