iOS 的RunLoop初识

     想多了解下iOS的运行机制,因此搜了搜runloop的资料看看,发现看了好几篇都没有看懂这个runloop用来干吗的。说到runloop是用来作什么的,只有一句话:oop

下来是Run Loop的使用场合:
1. 使用port或是自定义的input source来和其余线程进行通讯
2. 在线程(非主线程)中使用timer
3. 使用 performSelector…系列(如performSelectorOnThread, …)
4. 使用线程执行周期性工做

spa

却没有地方针对每一个方面说一下,到底这四个方面是怎么用的。其实我不是关心这四个功能怎么实现,我关心的是在这些功能里面,runloop起了什么做用。.net

  我很生气,看到一片片文章人云亦云,这些人怎么都不本身多思考一下?线程

  个人思惟习惯是,对于一个新的待了解的东西,我须要先知道它是用来干什么的、它在什么样的环境下使用而且起到了什么样的做用,而后才是去分析它的结构属性,具体怎么使用。首先没有对一个东西的定位,怎么去处理它的细节问题?code

  查了一些资料,只了解了一点:orm

一、RunLoop本质上是一个消息处理的机制,它不断的循环运行,判断线程中是否有须要处理的消息。这个理解来源于有篇文章说的一个例子:手机上一个程序开启,当你不去动它时,这个程序就好像死了同样,可是只要你触碰一个按钮,它就会立刻响应,就好像程序一直处于待命状态。这就是主线程的runloop一直在运行,监测事件。blog

二、有了这个理解,接下来就会想runloop会监测哪些事件。当你知道了它监测哪些事件,也就知道了在什么状况下须要使用开启runloop。回答这个问题就是上面蓝色那段话。由于主线程的runloop是默认开启的,因此咱们通常用到像:事件

[self performSelector:@selector(delay) withObject:nil afterDelay:1];
这样的方法,系统都会天然执行。但这个方法得以执行,实际须要靠主线程的runloop的,可是咱们很容易忽视了它。对于这个方法,文档有很好的解释:

This method sets up a timer to perform the aSelector message on the current thread’s run loop. The timer is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in the default mode.文档

If you want the message to be dequeued when the run loop is in a mode other than the default mode, use the performSelector:withObject:afterDelay:inModes: method instead. If you are not sure whether the current thread is the main thread, you can use the performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:modes: method to guarantee that your selector executes on the main thread. To cancel a queued message, use the cancelPreviousPerformRequestsWithTarget: or cancelPreviousPerformRequestsWithTarget:selector:object: method.get

这个方法会构建一个计时器,把 aSelector message运行在当前线程的runloop上。这个计时器配置为使用默认的模式运行。当计时器fires(NSTimer的fire方法是启动计时器,不过这里貌似是当计时器的时间到了,好比这里延时1秒,应该是计时器开启以后一秒)时,当前线程又会常识从runloop上面获取message,而后执行方法。若是当前runloop是以默认模式运行就会成功。而后说明了若是不是使用默认模式、不肯定当前是否主线程等状况下使用同类型的哪些其余方法。

  因此这个过程当中须要runloop作一个中介,在调用performSelector时runloop会保存要调用的方法信息,而后在时间到了,当前线程会从runloop里面获取方法信息,而后调用。因此须要runloop的参与,须要开启runloop。
  关于文档里面的aSelector message,个人理解是,使用SEL来调用方法,不是直接调用方法,是发送消息给方法的调用者(target),让它去执行方法。因此关键的东西是这个消息,这个消息至少应该保存方法的调用者(target)和方法自己的信息,可能还有参数。因此才会有aSelector message“方法消息”这么样的词,而后保存进runloop中的应该也是这么样一个消息。而runloop在它循环运行的过程当中,会不断监测相似的消息,在特定的时机调用。

  可能有不正确的地方,仅提供一种理解,欢迎指正。

  关于其余的输入源,也就是第一种使用场合,能够参考:这篇文章 的2.1.1输入源的部分。

相关文章
相关标签/搜索