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

标签 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<的写操作self.concurrentPhotoQueue 中,所以 _photosArray 的读取操作也需要在 self.concurrentPhotoQueue 中,否则使用 dispatch_sync是为了实现多读?

如果我在进行读操作时不使用dispatch_sync会发生什么?如:

- (NSArray *)photos
{
    __block NSArray *array;
    array = [NSArray arrayWithArray:_photosArray];
    return array;
}

非常感谢!

最佳答案

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

由于它是串行的,因此来自该队列的所有访问都会被序列化,并且如果应用程序中没有来自其他队列/线程的访问,则不会发生竞争条件。

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

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

关于ios - GCD为什么在读取共享资源时要使用dispatch_sync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48727343/

相关文章:

ios - 在UIView类别中创建UIBezierPath。没有显示

objective-c - 为什么当我触摸 UITableView 时会显示数据?

ios - 无法在 iOS 中设置启动图像

ios - 将 UIColor 值分配给宏

objective-c - 调用dispatch_sync()时发生死锁,即使它在另一个队列上

ios - 如何在前一个完整的情况下,依次调用多个函数

iphone - 自定义键盘为 iPhone sdk 中的应用程序制作?

ios - 使用 prepareForSegue 时键值编码错误

objective-c - 用 c 或 objective-c 编写的交互式命令行应用程序的简单示例?

ios - 什么队列应该委托(delegate)代码运行