在阅读共享资源时,我对使用dispatch_sync
有疑问。
我在Stack Overflow上搜索了几个问题(例如:GCD dispatch_barrier or dispatch_sync?),但我没有找到确切的答案。
我不明白为什么要使用
- (void)addPhoto:(Photo *)photo
{
if (photo) { // 1
dispatch_barrier_async(self.concurrentPhotoQueue, ^{ // 2
[_photosArray addObject:photo]; // 3
dispatch_async(dispatch_get_main_queue(), ^{ // 4
[self postContentAddedNotification];
});
});
}
}
- (NSArray *)photos
{
__block NSArray *array; // 1
dispatch_sync(self.concurrentPhotoQueue, ^{ // 2
array = [NSArray arrayWithArray:_photosArray];
});
return array;
}
我知道为什么要使用dispatch_barrier_async
,但我不知道为什么在阅读_photosArray
时使用dispatch_sync,我想_photosArray
的写操作在{ {1}},所以self.concurrentPhotoQueue
的读取操作也需要_photosArray
或者使用self.concurrentPhotoQueue
才能实现多次读取?
如果我在阅读手术时没有使用dispatch_sync
会怎样?如:
dispatch_sync
非常感谢!
答案 0 :(得分:3)
可能concurrentPhotoQueue
是一个串行队列。 concurrentPhotoQueue
的主要原因是同步对photos
数组的访问。
由于它是串行的,所有来自此队列的访问都是序列化的,如果您的应用程序中没有其他队列/线程的访问,则不会出现竞争条件。
写入访问可能是异步的,因为编写器通常不需要写入操作的结果。但读取必须同步完成,因为调用者必须等待结果。如果您的photos
方法使用dispatch_async
,则会在 array
方法返回后将结果写入photos
。因此,photos
始终会返回nil
。
您的photos
的未同步版本可能会产生竞争条件:_photosArray
可能会在复制其内容时进行修改,以便复制的项目数和数组长度不同。这可能会导致arrayWithArray:
内部崩溃。