同步调度会暂停执行代码,直到调度块完成。立即派遣异步回报,该块相对于调用代码异步执行:
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