在Apple NSRunLoop的文档中,有一个示例代码演示了在等待其他东西设置标志时暂停执行.

BOOL shouldKeepRunning = YES;        // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

我一直在使用它,但在调查性能问题时,我追踪到了这段代码.我使用几乎完全相同的代码(只是标志的名称不同:),如果我在设置标志后的行上加上NSLog(在另一种方法中),然后在while()后加上一行,两个日志(log)语句之间似乎会有几秒钟的随机等待.

在速度较慢或较快的机器上,延迟似乎没有什么不同,但在不同的运行中,延迟会有所不同,至少为几秒,最多为10秒.

我已经用下面的代码解决了这个问题,但原始代码不起作用似乎是不对的.

NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
while (webViewIsLoading && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil])
  loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];

使用此代码,设置标志时的日志(log)语句与while循环后的日志(log)语句现在的间隔始终小于0.1秒.

有人知道为什么原始代码会表现出这种行为吗?

推荐答案

Runloops可以是一个神奇的盒子,在那里事情就发生了.

基本上,你告诉runloopgo 处理一些事件,然后返回.或者,如果在达到超时之前未处理任何事件,则返回.

有了0.1秒的超时时间,你会更频繁地超时.runloop将启动,不处理任何事件,并在0.1秒内返回.偶尔它会有机会处理一个事件.

在距离future 超时的情况下,runloop将永远等待,直到它处理一个事件.所以当它返回给你时,它只是处理了某种事件.

短超时值将比无限超时消耗更多CPU,但使用短超时有很好的理由,例如,如果您想终止runloop正在运行的进程/线程.您可能希望runloop注意到一个标志已更改,它需要尽快退出.

你可能想和runloop观测者一起玩,这样你就可以确切地看到runloop在做什么.

更多信息请参见this Apple doc.

Objective-c相关问答推荐

Objective-C struct 的默认值以及如何测试

如何打印 NSMutableURLRequest?

NSTimeZone:localTimeZone 和 systemTimeZone 有什么区别?

定义缓存变量时在objective-c中使用static关键字

从日、月、年生成 NSDate

对 nil 对象进行快速枚举

如何获取 AppIcon 的 UIImage?

切换隐私设置将杀死应用程序

.m 文件中的空@interface 声明是做什么用的?

Objective-C 的文档生成器?

在 NSNumbers 的 NSArray 中查找最小值和最大值

如何在 iOS 上将图像旋转 90 度?

了解 performSegueWithIdentifier

iOS 5:对 UIAppearance 感到好奇

如何删除应用程序可访问的所有 keys 串项目?

使用单独的委托/数据源时的 UITableView 问题

在objective c中以自定义格式获取当前时间

在 iOS 7 上运行应用程序时显示黑条(4 英寸视网膜显示屏)

通过点击状态栏滚动到 UITableView 的顶部

如何使用图像和标签制作自定义 UIBarButtonItem?