![](/img/trans.png)
[英]What's the point in using dispatch_async + dispatch_get_main_queue for UI updates?
[英]What's the difference between performSelectorOnMainThread: and dispatch_async() on main queue?
我在修改线程内的视图时遇到问题。 我试图添加一个子视图,但显示大约需要 6 秒或更长时间。 我终于让它工作了,但我不知道究竟是怎么回事。 所以我想知道它为什么有效以及以下方法之间有什么区别:
dispatch_async(dispatch_get_main_queue(), ^{
//some UI methods ej
[view addSubview: otherView];
}
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView
waitUntilDone:NO];
NSNotification
方法 - 也花了大约 6 秒来显示观察者在我想修改的 viewController 中,与添加子视图的方法配对。[[NSNotificationCenter defaultCenter] postNotificationName:
@"notification-identifier" object:object];
作为参考,这些是在类ACAccountStore
CompletionHandler
中ACAccountStore
。
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 的并发编程指南,主队列会将排队的任务与来自应用程序运行循环的其他事件交错。 因此,如果事件队列中还有其他事件要处理,则调度队列中排队的块可能会先运行,即使它们是稍后提交的。
这篇文章是对performSelectorOnMainThread
与dispatch_async
的极好解释,也回答了上述问题。
您是否尝试过使用waitUntilDone=YES
的PerformSelectorOnMainThread
例如:
代码:
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];
我认为这可能会解决为什么PerformSelectorOnMainThread
需要这么长时间才能响应的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.