我有一些关于dispatch_barrier和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]; // 3
});
return array;
}在addPhoto方法中,它使用dispatch_barrier_async。在photos方法中,它使用dispatch_sync。我能把dispatch_barrier_async替换成dispatch_sync吗?如果是,这种方式在实际编程中流行吗?如果没有,请告诉我原因。非常感谢!
发布于 2015-09-19 09:22:10
实际上,在本例中,将dispatch_barrier_async替换为dispatch_sync将产生意想不到的行为。您可以使用并发队列访问照片--这意味着可以同时运行多个操作。可以从任意多个地方阅读_photosArray,只要一次就可以了。但坏的事情会发生,如果你试图改变它的内容,而有人读它。dispatch_barrier_async来了--也就是说,它允许您在并发队列中添加“序列化”。以这种方式发送的块将等待,直到所有其他操作停止、启动,并且当它执行时,没有人会在该队列上启动任何操作。
这是经典的读者-作家问题。
请随便问,如果有什么事情没有解释的话
更新1
不能在async方法中使用photos函数。dispatch_sync使您的方法等待任务执行。
根据数字我标记了执行流
- (NSArray *)photos
{
__block NSArray *array; //1. Here array is nil
dispatch_sync(self.concurrentPhotoQueue, ^{ //2. dispatch task and wait it ends execution
array = [NSArray arrayWithArray:_photosArray]; //3. Array filled with photos
});
return array; //4. Array filled with photos
}如果你使用async
- (NSArray *)photos
{
__block NSArray *array; //1. Here array is nil
dispatch_async(self.concurrentPhotoQueue, ^{ //2. dispatch task and move on
array = [NSArray arrayWithArray:_photosArray]; //4. Array filled with photos
});
return array; //3. Array is still nil
}更新2
几个dispatch_sync调用将同时运行。
例如,您有thread1和thread2。它们持有相同的物体。在某些地方他们同时打电话
thread1:NSLog(@"%@", [object photos]); thread2:NSArray *photos = [object photos];
这个调用将同时执行(即同时执行),但是同步地-线程冻结直到它们得到照片。
但是,如果你做了这样的事情
thread2:NSArray *photos = [object addPhoto:newPhoto]; thread1:NSLog(@"%@", [object photos]);
thread1会冻结,直到照片添加到数组中为止。但是,thread2不会等待,直到照片真正添加-它只是继续执行。
https://stackoverflow.com/questions/32647214
复制相似问题