同步調度會暫停執行代碼,直到調度塊完成。立即派遣異步回報,該塊相對於調用代碼異步執行:
dispatch_sync(somewhere, ^{ something });
// Reached later, when the block is finished.
dispatch_async(somewhere, ^{ something });
// Reached immediately. The block might be waiting
// to be executed, executing or already finished.
而且有兩種調度隊列,串行和並行的。序列號按照它們被添加的順序嚴格地逐個分派塊。當一個完成時,另一個開始。這種執行只需要一個線程。併發隊列同時並行地分派塊。那裏有更多的線程在使用。
如果您認爲合適,您可以混合使用sync/async dispatch和串行/併發隊列。如果您想要使用GCD來保護對關鍵部分的訪問,請使用單個串行隊列並分配此隊列上共享數據的所有操作(同步或異步,無關緊要)。這樣,總會有僅一個街區與共享數據進行操作:
- (void) addFoo: (id) foo {
dispatch_sync(guardingQueue, ^{ [sharedFooArray addObject:foo]; });
}
- (void) removeFoo: (id) foo {
dispatch_sync(guardingQueue, ^{ [sharedFooArray removeObject:foo]; });
}
現在,如果guardingQueue
是一個串行隊列,添加/刪除操作不能發生衝突,即使addFoo:
和removeFoo:
方法都是從不同的同時調用線程。
沒有「同步隊列」。有同步調度(等待塊完成)和異步調度(只是將該塊添加到隊列中)。併發隊列和並行隊列。連續隊列不能用於_implement_關鍵部分,但它們對於避免關鍵部分的需要非常有用。 – gnasher729