2013-07-05 46 views
2

在SO之前的一個問題之後,我現在正在比較兩個不同的宏中央調度隊列來試圖確定當前代碼是否在主線程上運行。我的問題很簡單:這是實現這一目標的有效方法嗎?還是有沒有這樣做,我沒有考慮到一些陷阱?這是比較兩個GCD隊列的正確方法嗎?

if (dispatch_get_current_queue() != dispatch_get_main_queue()) { 

    // We are currently on a background queue 

} else { 

    // We are on the main queue 
} 

乾杯

回答

6

當前隊列對主隊列相比是不檢查你是否在主線程上運行的有效途徑。

使用[NSThread isMainThread]pthread_main_np()明確檢查您是否在主線程上,如果這是您想知道的。

你可以在主線程上,當前隊列不是主隊列,你可以在主隊列上沒有當前線程作爲主線程(後者只有在調用dispatch_main()後仍然可用)。

在最近的版本,這是在dispatch_get_main_queue的CAVEATS部分明確記載(3)手冊頁:

dispatch_get_main_queue的()的結果可以或dispatch_get_current_queue的可能不等於()的結果,當被叫主線程。比較這兩者並不是測試代碼是否在主線程上執行的有效方法。 Foundation/AppKit程序應該使用[NSThread isMainThread]。 POSIX程序可能使用pthread_main_np(3)。

一般而言,您應避免使用隊列指針比較來影響程序邏輯。調度隊列存在於依賴樹(目標隊列層次結構)中,並且比較該樹中的單個葉節點而不考慮其相互依賴性並不能提供足夠的信息來做出安全的決策。

如果您確實需要基於隊列相關性的程序邏輯,請使用支持目標隊列的更清晰的API。

+0

感謝您的詳細回答,澄清一點......我正在進行此檢查以確保UI代碼在正確的隊列上運行。經過我的檢查方法的缺陷,我理解UI代碼需要在主隊列而不是主線程上運行嗎?我一直認爲兩者是一樣的,顯然並不總是如此。 – Sammio2

+0

反過來說,除非另有說明,任何與當前AppKit/UIKit對象交互的代碼都需要在主線程上運行。 – das

+0

好吧,這就是我原先想的......那麼爲什麼每個教程都要在世界中(包括關於調度隊列的蘋果文檔)稱爲調用'dispatch_sync(dispatch_get_main_queue(),^ {...});'爲了運行GCD隊列中的UI代碼,如果主隊列不總是主線程? – Sammio2

相關問題