ios - is this GCD implemented getter setter thread safe and work better than @synchronized? objc -


@interface viewcontroller () @property (nonatomic, strong) nsstring *somestring; @end  @implementation viewcontroller  @synthesize somestring = _somestring;  - (nsstring *)somestring {     __block nsstring *tmp;     dispatch_sync(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{         tmp = _somestring;     });     return tmp; }  - (void)setsomestring:(nsstring *)somestring {     __block nsstring *tmp;     dispatch_barrier_sync(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{         tmp = somestring;     });     _somestring = tmp; } @end 

some said it's better @synchronized way because locking handled down in gcd.

first off, setter makes no sense @ all, , using default concurrent queue not want. code should 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 made:

  • make setter mutation inside critical section
  • use private, per-instance concurrent queue instead of global default concurrent queue; submitting barrier blocks default concurrent queues doesn't think does. (see docs)
  • change dispatch_barrier_sync dispatch_barrier_async there's no point @ in waiting synchronously setter block return, there's no way stale read on current thread.
  • change property have copy semantics, practice value-semantic types (nsstring, etc.) important in cases property might read concurrently multiple threads.

the thing know that, in isolation, pattern provides no more "safety" atomic properties, should arguably use (less code, etc). performance question, yes, particular use, gcd out-perform @synchronized. one, allows concurrent reads, @synchronized serialize concurrent reads. without testing, expect atomic properties out-perform both. said atomic properties, , protecting single operations in way in general, rarely adequate concurrency strategy.


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

gradle error "Cannot convert the provided notation to a File or URI" -

python - NameError: name 'subprocess' is not defined -