最好的方法使NSRunLoop等待一个标志被设置? [英] Best way to make NSRunLoop wait for a flag to be set?

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

问题描述

NSRunLoop 有一个示例代码演示在等待其他设置的标志时暂停执行。

  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循环后的日志语句现在始终小于



任何人都知道为什么原始代码会展现这种行为?

解决方案<



基本上你告诉runloop去处理一些事件,然后返回。如果在超时被触发之前没有处理任何事件,则返回。



如果超时0.1秒,你的超时时间会更长。 runloop触发,不处理任何事件,并以0.1秒返回。有时它会有机会处理一个事件。



在你的distantFuture超时,runloop将等待foreever,直到它处理一个事件。所以当它返回给你,它只是处理了某种事件。



一个短暂的超时值将消耗相当多的CPU超过无限超时,但有很好的理由使用短暂的超时,例如,如果你想终止runloop运行的进程/线程。你可能希望runloop注意到一个标志已经改变,并需要救助。



您可能希望使用runloop观察器来玩,以便您可以准确地看到runloop正在做什么。



请参阅此Apple文档了解详情。


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]]);

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.

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];

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 can be a bit of a magic box where stuff just happens.

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.

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.

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.

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.

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

See this Apple doc for more information.

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

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