这个问题与 Obj-C 有关,因为代码是 Obj-C,但我也想了解 Swift 中的差异(如果有的话)。
iOS 中的黄金法则,您不应该在不使用调度 API(或其他)的情况下跨线程访问对象,因为这会导致竞争条件和其他“坏事”..
但是,从多个线程访问 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
在后台线程上被调用 1 次或多次,有时是快速连续调用。因此,_processing 检查以防止 _someOtherCallback
block 被多次调用。
也许将属性定义更改为原子并使用合成的 getter/setter 会更安全,但关于直接访问 bool var 的问题仍然存在。
编辑:需要明确的是,原子问题是一个附带问题。我的问题是所示代码在何处是安全的,或者它可能以某种方式导致内存损坏或竞争条件/死锁/其他
最佳答案
据我所知,atomic
属性将生成锁定 getter 与 setter 调用的访问器代码。这仅对retain
(可能还有copy
)属性很重要,因为所有其他属性只会简单地分配/返回一个值而无需事先检查。它们不会在更复杂的情况下帮助您,例如您在代码中描述的情况,当您首先检查该值然后根据它执行某些操作时。
特别是,如果您的callbackWithData
被多个 线程调用,它可能会评估_processing
并看到false
,但紧接着,另一个线程将 _processing
设置为 true
。没有 atomic
能帮到你。
如果这可能是个问题,您应该在 callbackWithData
中使用 @synchronized(...)
或一些 NSLock
来锁定您的方法的完整/最重要的部分。
关于ios - 可以跨线程安全地访问 bool var 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47347417/