![](/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.