Reputation: 79
I have some question about use dispatch_sync
when I read a shared resource.
I have searched several questions on Stack Overflow (such as: GCD dispatch_barrier or dispatch_sync?), but I didn't found an exact answer.
I don't understand that why to use
- (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;
}
I know why to use dispatch_barrier_async
,but I don't know why to use dispatch_sync when I read _photosArray
, I guess the write operation of _photosArray
is in the self.concurrentPhotoQueue
, so the read operation of _photosArray
also need in the self.concurrentPhotoQueue
or else use dispatch_sync
in order to achieve multi-read?
What will happen if I don't use dispatch_sync
when I do read operation? such as:
- (NSArray *)photos
{
__block NSArray *array;
array = [NSArray arrayWithArray:_photosArray];
return array;
}
Thank you very much!
Upvotes: 2
Views: 236
Reputation: 17721
Probably concurrentPhotoQueue
is a serial queue. The main reason for concurrentPhotoQueue
is to synchronize the access to the photos
array.
Since it is serial all accesses from this queue are serialized, and no race conditions may occur if there are no accesses from other queues / threads in your app.
Writing access may be asynchronous because the writer needs no result of the writing operation in general. But reading must be done synchronously, because the caller has to wait for the result. If your photos
method would use dispatch_async
it would write the result to array
after the photos
method has returned. Thus, photos
always would return nil
.
Your unsynchronized version of photos
might produce a race condition: _photosArray
could be modified while it copies its contents, such that the number of copied items and the length of the array differ. This could lead to a crash inside of arrayWithArray:
.
Upvotes: 3