这个问题与Obj-C有关,因为代码是Obj-C,但我也想了解Swift中的差异(如果有的话)。
iOS中的黄金法则,您不应在不使用调度apis(或其他)的情况下跨线程访问对象,因为这会导致竞争条件和其他“坏事”..
但是,从多个线程访问bool var是否安全?由于bool var只能有两种状态之一,这是否意味着以下内容始终是安全的:
@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
在后台线程上被调用一次或多次,有时是快速连续调用。因此,_processing检查以防止多次调用_someOtherCallback
块。
也许将属性定义更改为原子并使用合成的getter / setter会更安全,但是关于直接访问bool var的问题仍然存在。
编辑:要清楚,原子问题是一个侧面问题。我的问题是所显示的代码在哪里是安全的,或者它可能以某种方式产生内存损坏或竞争条件/死锁/其他
答案 0 :(得分:1)
据我所知,atomic
属性将生成访问代码,用于锁定getter和setter调用。这仅对retain
(可能是copy
)属性很重要,因为所有其他属性只是简单地分配/返回值而无需事先检查。他们在一个更复杂的场景中帮助你,比如你在代码中描述的场景,当你第一次检查价值然后根据它做一些事情时。
特别是,如果您的callbackWithData
被多个线程调用,它可能会评估_processing
并看到false
,但在此之后,另一个线程是我的将_processing
设置为true
。没有atomic
可以帮助你。
如果这可能是个问题,您应该在@synchronized(...)
中使用NSLock
或某些callbackWithData
来锁定方法的完整/最重要的部分。