簡體   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