2013-07-18 37 views
1

我曾經有一個幫助方法(靜態),它確保在正確的隊列上調用完成塊。GCD棄用方法

+ (void)_deadlockCheckBlock:(void(^)(void))block caller:(dispatch_queue_t)caller { 
    NSParameterAssert(block); 
    NSParameterAssert(caller); 
    if (caller == dispatch_get_current_queue()) { 
     block(); 
    } 
    else { 
     dispatch_async(caller, block); 
    }} 

我們克服

dispatch_get_current_queue() 

棄用我已經重寫使用get_main_queue方法的方法。

+ (void)_deadlockCheckBlock:(void(^)(void))block caller:(dispatch_queue_t)caller { 
    NSParameterAssert(block); 
    NSParameterAssert(caller); 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
    //This will ensure to be on the main queue 
    if (caller == dispatch_get_main_queue()) { 
     block(); 
    } 
    else { 
     dispatch_async(caller, block); 
    } 
    });} 

有沒有更好的方式來獲得相同的行爲,而不必去主隊列?

回答

3

有這個問題(其原因get_current_queue已過時)是可以有很多當前隊列。如果將dispatch_sync從一個隊列調度到另一個隊列,則兩者現在都是「當前」,因爲dispatch_sync對其中任何一個都會死鎖。與dispatch_set_target_queue相同。

避免死鎖的可靠方法是始終使用dispatch_async(或其他異步API;例如dispatch_group_notify),以避免重入控制流或傳遞足夠的附加信息以正確決定(如果使用隊列作爲鎖例如,你可以有一個「已經鎖定」的標誌)。

一般來說,需要遞歸鎖或模擬它們的事情的代碼(如使用當前隊列來決定是否dispatch_sync)是可能有一些不變量(鎖正在保護的那個)被破壞並且可能會工作的代碼無論如何,這是一個有點可怕的概念。的

+0

所以基本上不是調用_deadlockCheckBlock,只會叫 dispatch_async(來電顯示,{ 塊();} ; 到處 –

+0

在可行的範圍,是其他幫助兩個選項時,它不是。 。 –