GCD dispatch_barrier 还是 dispatch_sync?
GCD dispatch_barrier or dispatch_sync?
我有一些关于 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
吗?如果是,这种方式在实际编程中流行吗?如果不是,请告诉我原因。非常感谢!
实际上,在此示例中,将 dispatch_barrier_async
替换为 dispatch_sync
会产生意外行为。您有并发队列来访问照片 - 这意味着,它可以让您 运行 同时进行多项操作。一次从任意多个地方读取 _photosArray
是可以的。但是坏事发生了,如果你试图改变它的内容,而有人正在阅读它。 dispatch_barrier_async
来了 - 它可以让您将 "seriality" 添加到并发队列。以这种方式分派的块将等待,直到所有其他操作停止、开始,并且在其执行期间没有人会在该队列上开始任何操作。
如有不明之处,欢迎随时提问
更新 1
您不能在 photos
方法中使用 async
函数。
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。他们持有相同的对象 object。在某些地方他们同时打电话
线程 1:NSLog(@"%@", [object photos]);
线程 2 : NSArray *photos = [object photos];
此调用将并发执行(即在同一时间),但会同步执行 - 线程会冻结,直到它们获得照片。
但是,如果你做这样的事情
线程 2:NSArray *photos = [object addPhoto:newPhoto];
线程 1 : NSLog(@"%@", [object photos]);
您的 thread1 冻结,直到将照片添加到数组中。但是,thread2 不会等待,直到照片实际添加 - 它会继续执行。
我有一些关于 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
吗?如果是,这种方式在实际编程中流行吗?如果不是,请告诉我原因。非常感谢!
实际上,在此示例中,将 dispatch_barrier_async
替换为 dispatch_sync
会产生意外行为。您有并发队列来访问照片 - 这意味着,它可以让您 运行 同时进行多项操作。一次从任意多个地方读取 _photosArray
是可以的。但是坏事发生了,如果你试图改变它的内容,而有人正在阅读它。 dispatch_barrier_async
来了 - 它可以让您将 "seriality" 添加到并发队列。以这种方式分派的块将等待,直到所有其他操作停止、开始,并且在其执行期间没有人会在该队列上开始任何操作。
如有不明之处,欢迎随时提问
更新 1
您不能在 photos
方法中使用 async
函数。
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。他们持有相同的对象 object。在某些地方他们同时打电话
线程 1:NSLog(@"%@", [object photos]);
线程 2 : NSArray *photos = [object photos];
此调用将并发执行(即在同一时间),但会同步执行 - 线程会冻结,直到它们获得照片。
但是,如果你做这样的事情
线程 2:NSArray *photos = [object addPhoto:newPhoto];
线程 1 : NSLog(@"%@", [object photos]);
您的 thread1 冻结,直到将照片添加到数组中。但是,thread2 不会等待,直到照片实际添加 - 它会继续执行。