什么时候使用@atomic?

时间:2017-02-20 15:16:30

标签: ios objective-c

我已经看过这个问题:
What's the difference between the atomic and nonatomic attributes?

我了解@atomic并不保证线程安全,我必须使用其他机制(例如@synchronized)来实现这一点。基于此,我还不知道完全何时使用@atomic属性。我想知道仅使用@atomic使用案例

3 个答案:

答案 0 :(得分:5)

atomic属性的典型用例是在跨多个线程处理原始数据类型时。例如,假设您有一些后台线程正在进行一些处理,并且您有一些BOOL状态属性,例如isProcessComplete并且您的主线程想要检查后台进程是否完成:

if (self.isProcessComplete) {
    // Do something
}

在这种情况下,将此属性声明为atomic允许我们跨多个线程使用/更新此属性,而不需要更复杂的同步机制,因为:

  • 我们正在处理一个标量的原始数据类型,例如: BOOL;
  • 我们宣称它是atomic;和
  • 我们使用的是访问者方法(例如self.),而不是直接访问ivar。

在处理对象或其他更复杂的情况时,atomic通常是不够的。正如您所指出的那样,在实践中,单独atomic很少能够实现线程安全,这就是我们不经常使用它的原因。但是对于简单的,独立的原始数据类型,atomic可以是确保跨多个线程安全访问的简单方法。

答案 1 :(得分:1)

@atomic将向您保证,您将获得的价值不会是胡言乱语。可能的情况是从一个线程读取给定值并从另一个线程设置其值。然后,@atomic关键字将确保您获得整个值。现在重要的是,您获得的值不能保证是最近设置的值。

你的问题的第二部分,关于用例纯粹是间接的,取决于意图的实现。例如,如果您每隔一秒左右在列表上进行某种基于时间的更新,您可以使用atomic来确保您将获得整个值,更新您的列表的计时器可以确保您将在屏幕上获得最新数据或隐藏在某种隐含逻辑之下。

编辑:在@Rob发表评论后,我发现需要解释我答案的最后部分。在大多数情况下,atomic不足以完成工作。并且需要更好的解决方案,例如@synchronized

答案 2 :(得分:0)

atomic保证竞争线程将获取/设置整个值,无论您是设置原始类型还是指向对象的指针。通过nonatomic访问,可能会导致读取或写入中断,尤其是在处理64位值时。

atomic还保证对象指针在检索时不会成为垃圾: https://github.com/opensource-apple/objc4/blob/master/runtime/objc-accessors.mm#L58-L61

话虽如此,如果您指向的是可变对象,atomic不会为您提供有关该对象状态的任何保证。

atomic合适的,如果您正在处理:

  • 不变的对象
  • 原语(例如intcharfloat

atomic 不当

  • 对象或其任何后代属性是可变的

如果需要原始值或不可变对象的线程安全,这是防止可能发现的读取/写入中断的最快方法之一。