對於你的問題就關於凍結的提示第二部分:
當調用上的隊列dispatch_sync
,總是驗證此隊列尚未當前隊列(dispatch_get_current_queue()
)。因爲dispatch_sync
會將您的塊排列在作爲第一個參數傳遞的隊列上,然後將等待此塊被執行,然後繼續。
所以如果dispatch_get_current_queue()
和你排隊你的塊的隊列是相同的,也就是你的情況下的主隊列,主隊列將阻塞對dispatch_sync的調用,直到......主隊列執行塊,但是它不能,因爲隊列被阻塞,所以你在這裏有一個美麗的死鎖。
一個解決方案([編輯],直到iOS6的):
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_block_t block =^
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAuthenticationSuccess object:nil userInfo:ret];
};
if (dispatch_get_current_queue() == main)
block(); // execute the block directly, as main is already the current active queue
else
dispatch_sync(main, block); // ask the main queue, which is not the current queue, to execute the block, and wait for it to be executed before continuing
[編輯]注意,dispatch_get_current_queue()
僅用於調試目的,絕不生產。實際上,dispatch_get_current_queue
自iOS6.1.3開始已被棄用。
如果您處於主隊列(僅與主線程相關聯)的特定情況,您可以按照@意義事件的建議測試[NSThread isMainThread]
。
順便說一句,你確定你需要dispatch_sync
你的情況嗎? 我想稍後發送你的通知,避免阻塞,直到它被髮送,在你的情況下是可以接受的,所以你也可以考慮使用dispatch_async
(而不是使用dispatch_sync
並需要隊列比較條件),這將避免死鎖也是問題。
它鎖死,因爲你在排隊的主隊列塊 - 這是在主線程中 - 並告訴主線程等待塊完成。 –
由於您接受的答案根本不能解決您詢問的函數樁,所以我已將該部分從問題中刪除。死鎖問題已經被多次回答(並且也在文檔中):http://stackoverflow.com/questions/7816159/dispatch-sync-on-main-queue-hangs-in-unit-test,http ://stackoverflow.com/questions/10315645/app-blocks-while-dipatching-a-queue,http://stackoverflow.com/questions/10984732/gcd-why-cant-we-use-a-dispatch-sync在當前隊列中,但我認爲關於存儲GCD函數的問題非常有趣。 –
謝謝。如果我知道這是一個僵局問題,我可以適當地調整問題的範圍,或者通過搜索谷歌找到解決方案。知道如何存根dispatch_sync仍然很好,但也許這不是一個合適的解決方案。 – teubanks