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

标签 ios objective-c multithreading

这个问题与 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/

相关文章:

c++ - 可以在构造函数中创建 Pthreads 吗?

iphone - UITextView 作为自己的委托(delegate)意味着无限循环

ios - 可操作通知 - 第三个操作/按钮不起作用

ios - UIImageView -> UIScrollview,裁剪和裁剪 ScrollView 坐标

multithreading - Qt线程调用问题

c# - 收集拥有对象时如何终止工作线程?

ios - Swift 4 中更新数据库的两个日期的比较

objective-c - 核心图尺度以适应绘图问题

ios - 删除 TableView 行会引发线程 1 : signal SIGABRT

ios - 使用 CorePlot 绘制图形时出现问题