2013-07-24 75 views
8

既然dispatch_get_current_queue在iOS 6中已被棄用,我該如何使用dispatch_after在當前隊列中執行某些操作?如何在當前隊列中dispatch_after?

+0

你需要保持在同一隊列中,還是可以使用派遣到另一個隊列(通過dispatch_get_global_queue或get_main_queue) –

+0

需要保持不變。 – Boon

+3

僅供參考,請參閱http:// stackoverflow。com/questions/13237417/alternatives-dispatch-get-current-queue-for-completion-blocks-in-ios-6,http://stackoverflow.com/questions/12842166/how-can-i-replace- deprecated-method-dispatch-get-current-queue-from-ios5-to-io,和http://stackoverflow.com/questions/12806506/how-can-i-verify-that-i-am-running-on -a-given-gcd-queue-without-using-dispatch-g進行關於此主題的相關討論。 – Rob

回答

5

評論中的各種鏈接並沒有說「最好不要這樣做」。他們說你不能這樣做。您必須將您想要的隊列傳遞給已知的隊列。派遣隊列不具有「當前」的概念。塊通常從一個隊列饋送到另一個隊列(稱爲「目標」)。當你實際運行時,「當前」隊列並不真正有意義,依靠它可以(並且歷史上)導致死鎖。 dispatch_get_current_queue()從來沒有用於調度;這是一種調試方法。這就是爲什麼它被刪除的原因(因爲人們把它看作是有意義的東西)。

如果您需要這種更高級別的簿記,請使用追蹤其原始隊列的NSOperationQueue(並且具有更簡單的排隊模型,使「原始隊列」更有意義)。

有UIKit中使用的幾種方法是適當的:

  • 傳遞迴撥dispatch_queue作爲參數(這可能是在新的API最常用的方法)。例子見[NSURLConnection setDelegateQueue:]addObserverForName:object:queue:usingBlock:。請注意,NSURLConnection預計爲NSOperationQueue,而不是dispatch_queue。更高級別的API等等。
  • 回覆你正在處理的任何隊列,並留給接收者處理。這是回調傳統上的工作方式。
  • 要求在調用線程上有runloop,並在調用runloop上安排回調。這就是NSURLConnection歷史上排隊前的工作方式。
  • 除非另有說明,否則請務必在其中一個知名隊列(尤其是主隊列)上進行回調。我不知道這是在UIKit中完成的,但我通常在應用程序代碼中看到它,而且大多數情況下都是非常簡單的方法。
+2

我對你的最後一條語句有些抱怨:如果這是一個回調(比如說完成,錯誤或進度處理程序),那麼*主隊列*應該是被選作默認執行上下文的最少候選者。使用主隊列會增加死鎖的概率。這是圖書館設計者的一個壞習慣,源自愚蠢和錯誤的假設,異步任務的客戶想要在主線程上「做東西」。但是這使它變得更糟。 – CouchDeveloper

1

手動創建一個隊列並將您的調用代碼和您的dispatch_after代碼調度到該隊列中。這樣你可以保證這兩段代碼都是從同一個隊列中運行的。

+0

我們假設我無法發送我的調用代碼,說它來自靜態庫。 – Boon

+0

在這種情況下,會有一些間接的幫助嗎?不要傳遞你想調用的代碼,而要將你自己的代碼包裝到正確的隊列中。 –

0

必須這樣做可能是因爲需要黑客。你可以解決這個破解另一個黑客:

id block = ^foo() { 
    [self doSomething]; 
    usleep(delay_in_us); 
    [self doSomehingOther]; 
} 

相反usleep()的你可能會考慮到循環的運行循環。

雖然我不會推薦這個「方法」。更好的方法是有一些方法,它將隊列作爲參數,將塊作爲參數,然後在指定的隊列上執行塊。

而且,順便說一下,有辦法在一個塊執行,以檢查它是否運行在特定隊列 - 分別在任何隊列的,只要你有該隊列事先參考:使用功能dispatch_queue_set_specificdispatch_get_specific

相關問題