繁体   English   中英

主队列上的 performSelectorOnMainThread: 和 dispatch_async() 有什么区别?

[英]What's the difference between performSelectorOnMainThread: and dispatch_async() on main queue?

我在修改线程内的视图时遇到问题。 我试图添加一个子视图,但显示大约需要 6 秒或更长时间。 我终于让它工作了,但我不知道究竟是怎么回事。 所以我想知道它为什么有效以及以下方法之间有什么区别:

  1. 这有效 - 立即添加了视图:
dispatch_async(dispatch_get_main_queue(), ^{
    //some UI methods ej
    [view addSubview: otherView];
}
  1. 这需要大约 6 秒或更长时间才能显示:
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView
    waitUntilDone:NO];
  1. NSNotification方法 - 也花了大约 6 秒来显示观察者在我想修改的 viewController 中,与添加子视图的方法配对。
[[NSNotificationCenter defaultCenter] postNotificationName:
 @"notification-identifier" object:object];

作为参考,这些是在类ACAccountStore CompletionHandlerACAccountStore

accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
    if(granted) {
        // my methods were here
    }
}

默认情况下, -performSelectorOnMainThread:withObject:waitUntilDone:仅将选择器调度为在默认运行循环模式下运行。 如果 run loop 处于另一种模式(例如跟踪模式),它不会运行,直到 run loop 切换回默认模式。 您可以使用变体-performSelectorOnMainThread:withObject:waitUntilDone:modes:通过传递您希望它运行的所有模式)来解决此问题。

另一方面, dispatch_async(dispatch_get_main_queue(), ^{ ... })将在主运行循环将控制流返回到事件循环后立即运行该块。 它不关心模式。 因此,如果您也不想关心模式, dispatch_async()可能是更好的方法。

这可能是因为performSelectorOnMainThread:withObject:waitUntilDone:使用常见的运行循环模式将消息排队。 根据Apple 的并发编程指南,主队列会将排队的任务与来自应用程序运行循环的其他事件交错。 因此,如果事件队列中还有其他事件要处理,则调度队列中排队的块可能会先运行,即使它们是稍后提交的。

这篇文章是对performSelectorOnMainThreaddispatch_async的极好解释,也回答了上述问题。

您是否尝试过使用waitUntilDone=YESPerformSelectorOnMainThread

例如:

代码:

[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];

我认为这可能会解决为什么PerformSelectorOnMainThread需要这么长时间才能响应的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM