GCD为什么在读取共享资源时使用dispatch_sync

时间:2018-02-11 01:26:16

标签: ios objective-c grand-central-dispatch

在阅读共享资源时,我对使用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

非常感谢!

1 个答案:

答案 0 :(得分:3)

可能concurrentPhotoQueue是一个串行队列。 concurrentPhotoQueue的主要原因是同步对photos数组的访问。

由于它是串行的,所有来自此队列的访问都是序列化的,如果您的应用程序中没有其他队列/线程的访问,则不会出现竞争条件。

写入访问可能是异步的,因为编写器通常不需要写入操作的结果。但读取必须同步完成,因为调用者必须等待结果。如果您的photos方法使用dispatch_async,则会在 array方法返回后将结果写入photos 。因此,photos始终会返回nil

您的photos的未同步版本可能会产生竞争条件:_photosArray可能会在复制其内容时进行修改,以便复制的项目数和数组长度不同。这可能会导致arrayWithArray:内部崩溃。