First off, your setter makes no sense at all, and using the default concurrent queue is also probably not what you want. Your code should probably look more like:
@interface ViewController ()
@property (nonatomic, copy) NSString *someString;
@end
@implementation ViewController
{
dispatch_queue_t _stateGuardQueue;
}
- (instancetype)init
{
if (self = [super init])
{
_stateGuardQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
}
return self;
}
@synthesize someString = _someString;
- (NSString *)someString {
__block NSString *tmp;
dispatch_sync(_stateGuardQueue, ^{
tmp = _someString;
});
return tmp;
}
- (void)setSomeString:(NSString *)someString {
NSString* tmp = [someString copy];
dispatch_barrier_async(_stateGuardQueue, ^{
_someString = tmp;
});
}
@end
The changes I made:
- Make the setter actually do the mutation inside the critical section
- Use a private, per-instance concurrent queue instead of the global default concurrent queue; Submitting barrier blocks to default concurrent queues doesn't do what you think it does. (See the docs)
- Change
dispatch_barrier_sync
to dispatch_barrier_async
there's no point at all in waiting synchronously for the setter block to return, as there's no way to get a stale read on the current thread.
- Change the property to have
copy
semantics, which is always good practice with value-semantic types (NSString
, etc.) This is especially important in cases where the property might be read concurrently from multiple threads.
The thing to know is that, in isolation, this pattern provides no more "safety" than atomic properties, so you should arguably just use those (less code, etc). As to the performance question, yes, for this particular use, GCD will certainly out-perform @synchronized
. For one, it allows concurrent reads, where @synchronized
will serialize concurrent reads. Without testing, I would expect atomic properties to out-perform both. That said atomic properties, and protecting single operations in this way in general, are rarely an adequate concurrency strategy.