2013-02-16 80 views
1

看看這個代碼:爲什麼此代碼會停止程序執行?

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, nil),^
{ 
    NSLog(@"DISPATCH_QUEUE");//executed 

    //never goes further 
    dispatch_sync(dispatch_get_main_queue(),^
        { 
         NSLog(@"MAIN_QUEUE"); 
        }); 

    NSLog(@"END OF DISPATCH QUEUE"); 
}); 

我預計代碼照常運行程序流,但它總是在控制檯的話DISPATCH_QUEUE放,從來沒有更進一步。該程序停止。任何人都可以給出解釋它爲什麼這樣表現?幕後發生了什麼讓它停止?

回答

3

如果您從主隊列中運行此代碼(我認爲),您會遇到死鎖。主隊列被阻塞,直到您從第一次呼叫到dispatch_sync的塊完成。但是在這個塊內部,你等待另一個塊在主隊列上完成,直到外部塊完成,因爲主隊列是一個串行隊列。

您需要將其中一個呼叫更改爲dispatch_async

2

你可能已經陷入僵局;假設您的第一個電話dispatch_sync來自主線程。

在這種情況下,主線程正在等待第一次調度完成,但在該塊內部,您正試圖返回主線程......死鎖。

看來,你想:

  1. 做另一個隊列一些工作
  2. 更新UI
  3. 繼續做其他的隊列一些更多的工作

如果這是正確的,你可能想要使用NSOperation ...

2

dispatch_sync運行一個塊o在給定的隊列中等待它完成。在這種情況下,隊列是主調度隊列。主隊列以FIFO(先進先出)順序運行主線程上的所有操作。這意味着只要你調用dispatch_sync,你的新塊就會放在行尾,並且不會運行,直到隊列中的所有內容都完成爲止。

這裏的問題是,你剛剛入隊的塊位於等待在主線程上運行的行的末尾,但可能上面的代碼目前正在主線程上運行。直到當前方法完成使用主線程後,隊列末尾的塊才能訪問主線程。所以只有dispatch_async在這裏工作。

相關問題