Reputation: 1262
This question pertains to Obj-C as the code is Obj-C, but I'd like to understand the difference (if any) in Swift too.
The golden rule in iOS that you shouldn't access an object across threads without using dispatch apis (or other) because this can lead to race conditions and other 'bad things'..
Is it safe however, to access a bool var from multiple threads? Since a bool var can only have one of two states, does that mean the following is always safe:
@property(nonatomic) BOOL processing;
-(void)callbackWithData(NSData *)data {
if (_processing) {
return;
}
// set from a background thread here
_processing = YES;
NSString *res = [self doSomeWorkThatReturnsString:data];
dispatch_async(dispatch_get_main_queue(), ^{
_someOtherCallback(res)
// set from the main thread here
_processing = NO;
});
}
callbackWithData
gets called 1 or more times, sometimes in quick succession, on a background thread(s). Thus the _processing check to prevent the _someOtherCallback
block from being called multiple times.
Maybe changing the property definition to atomic and using the synthesized getter/setter would be safer, but the question about direct access to the bool var still stands.
EDIT: To be clear, the atomic thing is a side question. My question is about where or not the code as shown is safe, or might it somehow produce memory corruption or a race condition/deadlock/other
Upvotes: 2
Views: 679
Reputation: 10199
From my knowledge, atomic
properties will generate accessor code that locks the getter versus the setter call. This is only important for retain
(and maybe copy
) properties, since all others will just simply assign/return a value without prior checking. They won't help you in a more complex scenario, like the one you depicted in your code, when you first check the value and then do something depending on it.
Especially, if your callbackWithData
is called by mutiple threads, it might evaluate _processing
and see false
, but and direcly after this, another thread my set _processing
to true
. No atomic
could have helped you here.
If this might be a problem, you ought to use @synchronized(...)
or some NSLock
in your callbackWithData
to lock the complete / most important parts of your method.
Upvotes: 1