如果你想享受atomic
行为(这是您获得的默认行为,因为您没有指定nonatomic
限定符)此属性,您必须使用 getter (self.licensePlate
or [self licensePlate]
),不使用 ivar (_licensePlate
).
一般来说,在任何地方使用 getter 和 setter 通常是谨慎的做法,除了 (a)init
方法; (b) 和自定义访问器方法。开销可以忽略不计,并且您可以避免一系列潜在问题,包括原子性、内存语义、KVO、面向未来的代码(以防您在将来某个日期自定义访问器方法等)。
但是,假设您仅通过访问器方法(getter 和 setter)访问您的属性,atomic
限定符,如所描述的使用 Objective-C 编程:封装数据 https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW37确保您正在检索/设置的指针本身不会被另一个线程损坏:
[原子] 意味着合成访问器确保值始终由 getter 方法完全检索或通过 setter 方法完全设置,即使从不同线程同时调用访问器也是如此。
回答你的问题,如果另一个线程改变了licensePlate
财产,而frobnicate
方法正在另一个线程上运行,在该方法返回之前,原始对象不会被释放。
但需要明确的是,atomic
预选赛确实not确保线程安全。正如上述指南继续警告我们的那样:
Note:属性原子性并不等同于对象的线程安全性。
考虑一个XYZPerson
使用来自一个线程的原子访问器更改一个人的名字和姓氏的对象。如果另一个线程同时访问这两个名称,原子 getter 方法将返回完整的字符串(不会崩溃),但不能保证这些值是相对于彼此的正确名称。如果在更改之前访问名字,但在更改之后访问姓氏,则最终会得到一对不一致、不匹配的名称。
这个例子非常简单,但是当跨相关对象的网络考虑时,线程安全问题变得更加复杂。线程安全在以下内容中有更详细的介绍并发编程指南 https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008091.
So, it might使用线程安全frobnicate
在一个线程上同时在另一个线程上执行其他操作,但也可能不会。这取决于可以使用此牌照对象完成的所有不同操作。因为所提供的保护atomic
是如此简约,我们经常会采用一些同步(通过 GCD 串行队列或 GCD 读写器模式,或通过 中概述的任何同步方法)线程编程指南:同步 https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW1例如锁)来协调不同线程的交互。