ios - 了解NSRunLoop

任何人都可以解释什么是RunLoops? 据我所知NSRunLoop是与NSThread相关的东西对吗? 所以假设我创建一个类似的线程

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

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

在这个线程完成他的工作之后? 为什么用RunLoops或在哪里使用? 从Apple docs我已经阅读了一些东西,但对我来说并不清楚,所以请尽可能简单地解释

taffarel asked 2019-08-13T16:41:21Z
4个解决方案
179 votes

运行循环是一种抽象,(除其他外)提供了一种处理系统输入源(套接字,端口,文件,键盘,鼠标,定时器等)的机制。

每个NSThread都有自己的运行循环,可以通过currentRunLoop方法访问。

通常,您不需要直接访问运行循环,但有一些(网络)组件可以允许您指定它们将用于I / O处理的运行循环。

给定线程的运行循环将等待,直到其一个或多个输入源具有某些数据或事件,然后触发相应的输入处理程序以处理准备好的每个输入源。"。

在这样做之后,它将返回其循环,处理来自各种来源的输入,以及"睡眠" 如果没有工作要做。

这是一个非常高级别的描述(试图避免太多细节)。

编辑

试图解决评论。 我把它分成几块。

  • 这意味着我只能访问/运行在线程内运行循环   对?

确实。 NSRunLoop不是线程安全的,只能从运行循环的线程的上下文访问。

  • 有没有简单的例子如何添加事件到运行循环?

如果要监视端口,只需将该端口添加到运行循环中,然后运行循环将监视该端口的活动。

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

您还可以显式添加计时器

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode
  • 什么意味着它会回到它的循环?

运行循环将在每次迭代时处理所有就绪事件(根据其模式)。 您需要查看文档以了解有关运行模式的信息,因为这有点超出了一般答案的范围。

  • 当我启动线程时运行循环不活动?

在大多数应用程序中,主运行循环将自动运行。 但是,您负责启动运行循环并响应您旋转的线程的传入事件。

  • 是否有可能在线程外的Thread运行循环中添加一些事件?

我不确定你的意思。 您不会将事件添加到运行循环中。 您添加输入源和计时器源(来自拥有运行循环的线程)。 运行循环然后监视它们的活动。 当然,您可以提供来自其他线程和进程的数据输入,但输入将由运行循环处理,该循环正在运行运行循环的线程上监视这些源。

  • 这是否意味着有时我可以使用运行循环来阻止线程一段时间

确实。 事实上,一个运行循环将保持" 在事件处理程序中,直到该事件处理程序返回。 你可以在任何应用程序中看到这个就足够了。 为睡眠的任何IO操作(例如,按下按钮)安装处理程序。 您将阻止主运行循环(以及整个UI),直到该方法完成。

这同样适用于任何运行循环。

我建议你阅读关于运行循环的以下文档:

[https://developer.apple.com/documentation/foundation/nsrunloop]

以及如何在线程中使用它们:

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

Jody Hagins answered 2019-08-13T16:44:42Z
8 votes

RunLoops有点像盒子里的东西刚刚发生。

基本上,在RunLoop中,您将处理一些事件然后返回。 如果在超时被触发之前没有处理任何事件,则返回。你可以说它类似于异步NSURLConnections,在后台处理数据而不会干扰你当前的循环,但同时你需要同步数据。这可以在RunLoop的帮助下完成,它使您的异步NSURLConnection并在调用时提供数据。您可以像这样使用RunLoop:

NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];

while (YourBoolFlag && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) {
    loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
}

在此RunLoop中,它将一直运行,直到您完成其他一些工作并将YourBoolFlag设置为false。

同样,您可以在线程中使用它们。

希望这对你有所帮助。

Akshay Sunderwani answered 2019-08-13T16:45:33Z
2 votes

运行循环是交互式应用程序的分离   命令行工具。

  • 使用参数启动命令行工具,执行命令,然后退出。
  • 交互式应用程序等待用户输入,做出反应,然后继续等待。

从这里

它们允许你等到用户点击并做出相应的响应,等到你获得completionHandler并应用它的结果,等到你得到一个计时器并执行一个功能。 如果你没有跑圈,那么你就无法收听/等待用户点击,你不能等到网络通话发生,你就无法在x分钟内被唤醒。

同样来自这个评论:

后台线程没有自己的runloops,但你可以添加   一。 例如。 AFNetworking 2.x做到了。 这是尝试和真正的技术   NSURLConnection或NSTimer在后台线程上,但我们不这样做   我们自己已经很多了,因为新的API消除了这样做的需要。 但   似乎URLSession确实,例如,这里是简单的请求,运行[见图像的左侧面板]   主队列上的完成处理程序,你可以看到它有一个运行   循环背景线程

Honey answered 2019-08-13T16:46:44Z
0 votes

运行循环是与线程相关的基础架构的一部分。 运行循环是一个事件处理循环,用于计划工作并协调传入事件的接收。 运行循环的目的是在有工作时保持线程忙,并在没有线程时让线程进入休眠状态。

从这里


CFRunLoop最重要的特性是CFRunLoopModes。 CFRunLoop使用“运行循环源”系统。 源在一个或多个模式的运行循环中注册,并且运行循环本身在给定模式下运行。 当事件到达源时,如果源模式与运行循环当前模式匹配,则仅由运行循环处理。

从这里

dengApro answered 2019-08-13T16:47:23Z
translate from https://stackoverflow.com:/questions/12091212/understanding-nsrunloop