聊聊 iOS 中的 RunLoop 考题 (中文版)

聊聊 iOS 中的 RunLoop 考题 (中文版)_第1张图片
Run (跑) Loop (圈)

Run Loop 是与进程相关的基础设施。Run Loop 是来协调待接受的事件、安排调度的,事件处理循环。Run Loop 的作用就是,有任务,开起进程,没任务,休眠进程。

翻译自苹果的 runloop 文档


上一段代码 ,与 NSRunLoop 和 NSThread 相关,

NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];

-(void) someMethod
{
    NSLog(@"operation");
}


Run Loop 是处理 sockets 网络, ports 端口, files 文件 , keyboard 键盘 , mouse 鼠标 , timers 计时器 的机制的一层抽象。

NSThread 都有着专属的 Run Loop ,可以通过 currentRunLoop 方法访问。

一般是不需要直接访问 Run Loop 的。可以用网络相关的组件指定Run Loop , 处理 IO 输入输出。

等着输入源有数据 / 事件,给定线程的 Run Loop 就会让合适的输入处理函数处理有数据 / 事件,等待执行的输入源。

执行完后,Run Loop 会还原。如果有其他输入源的数据 / 事件, 该线程的 Run Loop 会处理;如果无, 该线程会进入休眠状态。

以上是抽象后的简单描述,省略了很多细节。


继续解释:

run loop 是不是只能在线程内部访问,执行?

是的。 NSRunLoop 不是线程安全的。所以只在跑这个 run loop 的线程的上下文中获取比较好。


来一个简单地给 run loop 添加事件的例子?

上 :

如果想要监听 port , 添加该 port 到 run loop 就可以了,这个 run loop 就会监听该 port 的活动,

- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode

也可以直接给 run loop 添加计时器,

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode

Run Loop 会还原,什么意思?

每一次迭代中,run loop 会按照他的 mode ,处理所有的条件满足的事件。这个问题与 run loop 的 mode 相关,要看文档。


开线程的时候,Run Loop 没有被唤醒?

大多应用,主线程的 Run Loop 自动去跑。

人为开的线程,要去开启对应的 Run Loop ,响应传入的事件。

{

所以, 开线程,用 timer ,需要手动开启对应的 Run Loop

}


能不能在线程外,给线程的 Run Loop 添加事件?

什么意思哈?

不是给 Run Loop 添加事件。是在持有 Run Loop 的线程中,添加输入源,例如计时器事件源。该 Run Loop 就会监听事件源的活动。

输入的数据可以来自其他的线程 / 进程。处理输入的 Run Loop 是监听这些事件源的 Run Loop ,跑在线程上。


是不是,有时候可以用 Run Loop 堵塞线程一会?

是的。事件处理返回前, Run Loop 会驻留处理事件。任意 app 中,都会轻易发现这点。任意的IO操作中,例如点击按钮,加一个睡眠函数。方法完成了,主 Run Loop 就被阻塞了,整个 UI 都挂了。

任何的 Run Loop 中,都适用。


Run, RunLoop, Run! RunLoop , 跑起来

交互性的应用与命令行程序的区别,就是 RunLoop . 使用命令行程序, 先配参数开起,执行命令,就结束了。交互性的应用等待用户输入,给用户反馈,然后一直等。很多长周期的进程中,都有这种机制。举个经典的例子,服务端中的

        while( 1 ){ select( ); }

...

CFRunLoop 中最重要的特性是 CFRunLoopModes , RunLoop 的模态。 RunLoop 处理 Run Loop Sources , Run Loop 的事件源。事件源登记在 Run Loop 的一到多个模态上。 Run Loop 必须在一个给定模态上跑。事件源新加了事件,只要当该事件源与Run Loop 当前的模态一致,Run Loop 才处理该事件。

Mode 分为不同的模式, Common, UITracking ... , 也是一种状态。 个人觉得,可以叫模态。


聊聊 iOS 中的 RunLoop 考题 (中文版)_第2张图片
辛苦啦

建议阅读 Run Loop 文档,https://developer.apple.com/documentation/foundation/nsrunloop

线程中 Run Loop 的应用,

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1


说明: 为了有意思一些, 我采取了意译。

本文翻译自

  • Stack Over Flow Understanding NSRunLoop

  • 苹果的 runloop 文档

  • Run, RunLoop, Run!

你可能感兴趣的:(聊聊 iOS 中的 RunLoop 考题 (中文版))