让 NSRunLoop 等待设置标志的最佳方法? [英] Best way to make NSRunLoop wait for a flag to be set?

查看:19
本文介绍了让 NSRunLoop 等待设置标志的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NSRunLoop 有示例代码演示了在等待其他东西设置标志时暂停执行.

In the Apple documentation for NSRunLoop there is sample code demonstrating suspending execution while waiting for a flag to be set by something else.

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

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

I have been using this and it works but in investigating a performance issue I tracked it down to this piece of code. I use almost exactly the same piece of code (just the name of the flag is different :) and if I put a NSLog on the line after the flag is being set (in another method) and then a line after the while() there is a seemingly random wait between the two log statements of several seconds.

延迟在较慢或较快的机器上似乎没有什么不同,但在每次运行之间确实有所不同,至少几秒到 10 秒.

The delay does not seem to be different on slower or faster machines but does vary from run to run being at least a couple of seconds and up to 10 seconds.

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

I have worked around this issue with the following code but it does not seem right that the original code doesn't work.

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

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

using this code, the log statements when setting the flag and after the while loop are now consistently less than 0.1 seconds apart.

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

Anyone any ideas why the original code exhibits this behaviour?

推荐答案

Runloops 就像一个神奇的盒子,可以让事情发生.

Runloops can be a bit of a magic box where stuff just happens.

基本上你是在告诉 runloop 去处理一些事件然后返回.或者,如果在超时之前没有处理任何事件,则返回.

Basically you're telling the runloop to go process some events and then return. OR return if it doesn't process any events before the timeout is hit.

0.1 秒超时,您会更频繁地超时.runloop 触发,不处理任何事件并在 0.1 秒内返回.偶尔它会有机会处理一个事件.

With 0.1 second timeout, you're htting the timeout more often than not. The runloop fires, doesn't process any events and returns in 0.1 of second. Occasionally it'll get a chance to process an event.

在您的 distanceFuture 超时后,runloop 将永远等待,直到它处理一个事件.所以当它返回给你时,它只是处理了某种事件.

With your distantFuture timeout, the runloop will wait foreever until it processes an event. So when it returns to you, it has just processed an event of some kind.

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

A short timeout value will consume considerably more CPU than the infinite timeout but there are good reasons for using a short timeout, for example if you want to terminate the process/thread the runloop is running in. You'll probably want the runloop to notice that a flag has changed and that it needs to bail out ASAP.

您可能想要玩转 runloop 观察者,以便您可以准确地看到 runloop 正在做什么.

You might want to play around with runloop observers so you can see exactly what the runloop is doing.

参见 此 Apple 文档 了解更多信息.

See this Apple doc for more information.

这篇关于让 NSRunLoop 等待设置标志的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆