2014-05-15 108 views
1

我已經看到dispatch_async調用dispatch_async與dispatch_async調用dispatch_sync的常見習語。dispatch_async調用dispatch_async vs dispatch_async調用dispatch_sync

在某些情況下,後者可以用前者代替。問題是,在什麼情況下你只能使用一個而不使用另一個?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // 
    }); 
}); 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // 
    }); 
}); 

回答

1

第二個選項纔有意義,如果你有dispatch_async內的其他代碼,你想裏面dispatch_sync完成的代碼之後執行的代碼。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    // A) Some code here 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // B) some code here 
    }); 

    // C) Some code here 
}); 

這確保A被執行,然後B(在主線程上),然後C(在後臺線程上但在B代碼完成後)。

如果沒有C代碼,則使用dispatch_syncdispatch_async作爲內部調度結果的結果相同。

+0

如果沒有C代碼,邏輯效果是一樣的,但實際效果是你保持一個線程佔用但什麼都不做。 –

1

我會說你應該努力避免阻塞線程。如果您試圖使用dispatch_sync(),因爲在您正在對主線程分流的內容完成後要運行代碼,則應該使用「延續傳遞」編碼風格。您提交給主隊列的任務應將新任務提交到併發隊列。因此,代碼可能看起來像:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    // A) Some code here 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // B) some code here 

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      // C) Some code here 
     }); 
    }); 
}); 

使用dispatch_sync()的主要原因是,當你實現一個固有的同步接口,但你需要派遣任務隊列來實現這一目標。這通常只發生在使用串行調度隊列(或併發隊列上的屏障任務)來保護共享資源時。

鑑於原始代碼已經有一個dispatch_async()調用,它不能實現同步接口。