可以跨线程安全地访问bool var吗?

时间:2017-11-17 09:37:04

标签: ios objective-c multithreading

这个问题与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的问题仍然存在。

编辑:要清楚,原子问题是一个侧面问题。我的问题是所显示的代码在哪里是安全的,或者它可能以某种方式产生内存损坏或竞争条件/死锁/其他

1 个答案:

答案 0 :(得分:1)

据我所知,atomic属性将生成访问代码,用于锁定getter和setter调用。这仅对retain(可能是copy)属性很重要,因为所有其他属性只是简单地分配/返回值而无需事先检查。他们在一个更复杂的场景中帮助你,比如你在代码中描述的场景,当你第一次检查价值然后根据它做一些事情时。

特别是,如果您的callbackWithData多个线程调用,它可能会评估_processing并看到false,但在此之后,另一个线程是我的将_processing设置为true。没有atomic可以帮助你。

如果这可能是个问题,您应该在@synchronized(...)中使用NSLock或某些callbackWithData来锁定方法的完整/最重要的部分。

相关问题