我已经看过这个问题:
What's the difference between the atomic and nonatomic attributes?
我了解@atomic
并不保证线程安全,我必须使用其他机制(例如@synchronized
)来实现这一点。基于此,我还不知道完全何时使用@atomic
属性。我想知道仅使用@atomic
的使用案例。
答案 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
是合适的,如果您正在处理:
int
,char
,float
) atomic
不当:
如果需要原始值或不可变对象的线程安全,这是防止可能发现的读取/写入中断的最快方法之一。