在苹果文档中NS运行循环 http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html#//apple_ref/occ/instm/NSRunLoop/run有示例代码演示了在等待其他事件设置标志时暂停执行。
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
我一直在使用它并且它有效,但在调查性能问题时我将其追溯到这段代码。我使用几乎完全相同的代码(只是标志的名称不同:),如果我放一个NSLog
在设置标志后的行上(以另一种方法),然后在设置后的行上while()
两个日志语句之间有几秒钟的看似随机的等待。
在较慢或较快的机器上,延迟似乎没有什么不同,但每次运行的延迟确实不同,至少几秒,最多 10 秒。
我已经使用以下代码解决了这个问题,但原始代码不起作用似乎不正确。
NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
while (webViewIsLoading && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil])
loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
使用此代码,设置标志时和 while 循环之后的日志语句现在始终相隔不到 0.1 秒。
有人知道为什么原始代码会表现出这种行为吗?
运行循环有点像一个神奇的盒子,事情就会发生。
基本上你是告诉运行循环去处理一些事件然后返回。或者,如果在超时之前未处理任何事件,则返回。
如果超时时间为 0.1 秒,那么您会更频繁地遇到超时。 runloop 触发,不处理任何事件并在 0.1 秒内返回。有时它会有机会处理事件。
由于远程未来超时,运行循环将永远等待,直到处理事件。因此,当它返回给您时,它刚刚处理了某种事件。
短超时值将比无限超时消耗更多的 CPU,但是使用短超时有充分的理由,例如,如果您想终止正在运行 runloop 的进程/线程。您可能希望 runloop 注意到旗帜已经改变,需要尽快摆脱困境。
您可能想尝试一下 runloop 观察者,这样您就可以准确地看到 runloop 正在做什么。
See 这个苹果文档 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW22了解更多信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)