如果performSelectorOnMainThread:waitUntilDone:从主线程调用,它什么时候执行?

时间:2013-07-11 23:56:16

标签: objective-c multithreading

我正在编写一个使用NSURLConnection来使用异步Web请求的应用程序,因此我运行了多个线程。为了确保我的应用程序的主要逻辑发生在一个线程上,我正在大量使用performSelectorOnMainThread:waitUntilDone:。有时虽然,我在主线上运行这个,这激起了我的好奇心。

如果在主线程中调用performSelectorOnMainThread:waitUntilDone:?它是否与performSelector:的行为相同?如果waitUntilDone:YES,该怎么办?如果是NO怎么办?

编辑:我发现当waitUntilDone:YES时,选择器会立即执行(几乎),但如果waitUntilDone:为{{1},我无法知道它何时被执行}}

3 个答案:

答案 0 :(得分:13)

performSelectorOnMainThread:withObject:waitUntilDone:

是一种在main thread的{​​{1}}上发送邮件的方法。参数application中的boolean值指定您是否要阻止waitUntilDone:执行指定的main thread

例如 -

如果你写了这两行 -

selector

这是打印方法 -

[self performSelectorOnMainThread:@selector(print) withObject:nil waitUntilDone:YES];

NSLog(@"Hello iPhone");

然后你会得到这个o / p

- (void) print
{
    NSLog(@"Hello World");
}

所以它首先暂停执行你的Hello World Hello iPhone 并打印“Hello World”,然后再次执行主线程并打印“Hello iPhone”,因为你在main thread中指定了YES

但如果您在waitUntilDone:中指定了NO,那么它将按照这样打印 -

waitUntilDone:

它清楚地表明它将您执行指定Hello iPhone Hello World 的请求放在selector中,并且操作系统将其queue释放,并按您的请求执行。

main threadperformSelectorOnMainThread:withObject:waitUntilDone:拨打main thread对其执行没有任何影响,具体取决于您在secondary thread中指定的内容

了解更多信息 -

NSObject Class Reference

答案 1 :(得分:1)

If the current thread is also the main thread, and you pass YES,
the message is performed immediately, otherwise the perform is
queued to run the next time through the run loop.

如果是,则可以在performSelectorOnMainThread:withObject:waitUntilDone:返回之前执行。

  

我发现当waitUntilDone:为YES时,选择器会立即执行(几乎),但是如果waitUntilDone:为NO,我无法弄清楚它是什么时候执行。

关于运行循环的一点:你的主线程有一个运行循环。这或多或少会阻止线程退出。运行循环管理待办事项列表。当它的工作完成后,它暂停执行该线程一段时间。然后它会在稍后醒来,看看是否有工作要做。

工作量可能会有很大差异(例如,它可能会在唤醒时和执行选择器之间进行一些非常繁重的绘图或文件i / o。因此,它不是真正精确计时的好工具,但是它应该足以知道它是如何工作的以及实现如何将工作添加到运行循环中。

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

答案 2 :(得分:1)

如果waitUntilDone:为YES,它将作为立即函数调用。

如果waitUntilDone:为NO,那么它会将呼叫与所有其他线程的呼叫一起排队。

  

此方法将消息排入主线程的运行循环   使用常见的运行循环模式 - 即与之相关的模式   NSRunLoopCommonModes常量。作为其正常运行循环的一部分   处理时,主线程将消息出列(假设是   在一个常见的运行循环模式中运行)并调用所需的   方法

如上所述,绘图和I / O等内容优先于队列中的任何内容。一旦主线程在下一个事件循环中有时间进行队列服务,那么还有一些其他细节使得它不像在先出先计数时那么简单:

1)dispatch_async()阻止忽略模式。

2)具有特定模式参数的performSelector变体 - 例如事件跟踪 - 可能优先于在该特定模式下运行的循环中具有默认公共模式参数的变量。

作为一般规则,如果您想要可预测的计时行为,您应该使用低级GCD调度函数,这些函数不考虑运行循环模式等更高级别的考虑因素。

相关问题