nonatomic atomic 属性宣言的作用(以 附带 retain关键字举例)iOS开发
转载说明(谢谢)
http://blog.****.net/a21064346/article/details/8086701
点击打开链接
昨天写了一个 关于 atomic 原子操作的文章,想起刚学ios开发时一直没有弄明白的问题
nonatomic
@property (nonatomic,retain)NSString *name;
为什么要这样来声明 成员变量 name?
可能有一些人对这个也不是很清楚,一直都是带点模糊的感觉。那么我就把我的理解 分享给大家。
首先,atomic,nonatomic 是一对反义词。前者使用 原子性,后者不使用 原子性。关于原子操作,可以看我写过的一个blog来理解
这里是地址:
http://blog.****.net/a21064346/article/details/8076972
atomic 是属性声明关键字中默认的一个属性,如果你没有对 原子性进行一个声明(atomic or nonatomic),那么系统会默认你选择的是atomic。
atomic 声明属性的成员变量,它没有一个“加锁”的概念,我认为,它会直接从内存中取最新的value,即 声明成员变量的 最新value。
nonatomic则会有一个加锁的保护,防止你数据取到一半,数据释放了,或者数据 还在其他线程中正在写入。这就避免了 取到的数据不是你预期的那一个。
结合下面一段代码来进行理解:
name setter方法:(重写)
- -(void) setName:(NSString*)string
- {
- if (name)
- {
- [name release];
- // what happens if the second thread jumps in now !?
- // name may be deleted, but our 'name' variable is still set!
- name = nil;
- }
- name = [string retain];
- ...
- }
如果name声明在 class A中,class B 和 class C来负责 取用。
我们假设有 3个线程同时 访问到了A中的 name 。线程1:我正在给我的class A name 一个新的value。线程2:class B 要从A 得到当前的name。线程3:class C 要从A得到当前的name。而name声明时,没有加non atomic的关键字。那么,B 和 C 取道的数值可能会 不一样。可能是nil,也可能是 string,也可能是最初始的那一个value。这是不 安全的
这里是 一个app的文档。我在一些地方标注了红色,方便大家理解。
Properties Are Atomic by Default
By default, an Objective-C property is atomic. This means that the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads.
Because the internal implementation and synchronization of atomic accessor methods is private, it’s not possible to combine a synthesized accessor with an accessor method that you implement yourself. You’ll get a compiler warning if you try, for example, to
provide a custom setter for an atomic readwrite
property but leave the compiler to synthesize the getter.
You can use the nonatomic
property attribute to specify that synthesized accessors simply set or return a value directly, with no guarantees about what happens
if that same value is accessed simultaneously from different threads. For this reason, it’s faster to access a nonatomic property than an atomic one, and it’s fine to combine a synthesized setter, for example, with your own getter implementation:
这段话,说明了nonatomic的faster的原因,因为它是直接访问 内存的地址。(因为有 类似于“防死锁”的保护)。它不需要去关心 其他线程如何去改变这个数值,它只需得到最后的结果。 那么就不会有死锁的现象,也就是 取到的数值 一定是 最后的东西,所有相关线程 用完后,写入进内存的东西。
@interface XYZObject : NSObject |
@property (nonatomic) NSObject *nonatomicObject; |
@end |
@implementation XYZObject |
- (NSObject *)nonatomicObject { |
return _nonatomicObject; |
} |
// setter will be synthesized automatically |
@end |
Note: Property atomicity is not synonymous with an object’s thread safety.
Consider an XYZPerson
object in which both a person’s first and last names are changed using atomic accessors from one thread. If another thread accesses
both names at the same time, the atomic getter methods will return complete strings (without crashing), but there’s no guarantee that those values will be the right names relative to each other. If the first name is accessed before the change, but the last
name is accessed after the change, you’ll end up with an inconsistent, mismatched pair of names.
This example is quite simple, but the problem of thread safety becomes much more complex when considered across a network of related objects. Thread safety is covered in more detail in Concurrency Programming Guide.
上面一段话是 说明 atomicity的 不安全性。因为 atomic 不保证 当前数据 是否会线程安全,没有一个互斥的保护。大家都可以访问当前cpu中(寄存器中)正在用的value
- 1楼xudehengnx4天前 22:57
- atomic 的区别说反了吧?
- Re: a210643463天前 17:43
- 回复xudehengnxnn没有说 反啊。 n对于这个的具体问题,你再看看我之后的添加修改,我又把官方doc的解释对照着来 分析了