我对 NSRunLoop 的 runMode:beforeDate
方法的正确使用有疑问。
我有一个辅助后台线程,用于在收到委托(delegate)消息时对其进行处理。
基本上,我有需要在后台线程上执行的进程密集型逻辑。
所以,我有 2 个对象,ObjectA
和 AnotherObjectB
。
ObjectA
初始化 AnotherObjectB
并告诉 AnotherObjectB
开始做它的事情。 AnotherObjectB
异步工作,因此 ObjectA
充当 AnotherObjectB
的委托(delegate)。现在,需要在委托(delegate)消息中执行的代码需要在后台线程上完成。因此,对于 ObjectA
,我创建了一个 NSRunLoop,并执行了类似的操作来设置运行循环:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (aCondition);
在“完成委托(delegate)消息”中的某个位置设置aCondition
。
我正在获取所有委托(delegate)消息,并且它们正在该后台线程上进行处理。
我的问题是:这是正确的方法吗?
我问这个问题的原因是因为[NSDate distanceFuture]
是一个跨越几个世纪的日期。所以基本上,runLoop 直到“distantFuture”才会超时——在那之前我绝对不会使用我的 Mac 或这个版本的 iOS。 >_<
但是,我不希望运行循环运行那么长时间。我希望运行循环在调用最后一个委托(delegate)消息后立即完成,以便它可以正确退出。
此外,我知道我可以设置间隔更短的重复计时器,但这不是最有效的方法,因为它类似于轮询。相反,我希望线程仅在委托(delegate)消息到达时才工作,并在没有消息时休眠。那么,我正在采取的方法是正确的方法,还是有其他方法可以做到这一点。我阅读了文档和指南,并根据我从阅读它们中了解到的内容进行了设置。
但是,如果不完全确定,最好向这个很棒的社区寻求意见和确认。
所以,提前感谢您的所有帮助!
干杯!
最佳答案
代码是in the docs :
If you want the run loop to terminate, you shouldn't use this method. Instead, use one of the other run methods and also check other arbitrary conditions of your own, in a loop. A simple example would be:
BOOL shouldKeepRunning = YES; // global NSRunLoop *theRL = [NSRunLoop currentRunLoop]; while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
where
shouldKeepRunning
is set toNO
somewhere else in the program.
在最后一条“消息”之后,取消设置 shouldKeepRunning
(与运行循环在同一线程上!),它应该完成。这里的关键思想是您需要向运行循环发送一个事件,以便它知道停止。
(另请注意,NSRunLoop 不是线程安全的;我认为您应该使用 -[NSObject PerformSelector:onThread:...]
。)
或者,如果它适合您的目的,请使用后台调度队列/NOperationQueue(但请注意,执行此操作的代码不应触及运行循环;从调度队列/NSOperationQueue 工作线程启动 NSURLConnection 等操作将可能会导致问题)。
关于ios - NSRunLoop的runMode :beforeDate: - the correct approach for setting the "beforeDate",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13314135/