atomic 与 nonatomic的区别

atomic 和 nonatomic 的区别在于,系统自动生成的 getter/setter 方法不一样。如果你自己写 getter/setter,那 atomic/nonatomic/retain/assign/copy 这些关键字只起提示作用,写不写都一样。
**atomic **: 变量默认是有该有属性的,这个属性是为了保证在多线程的情况下,编译器会自动生成一些互斥加锁的代码,避免该变量的读写不同步的问题。
nonatomic : 如果该对象无需考虑多线程的情况,这个属性会让编译器少生成一些互斥代码,可以提高效率。
atomic
1.是默认的
2.会保证 CPU 能在别的线程来访问这个属性之前,先执行完当前流程
3.速度不快,因为要保证操作整体完成
nonatomic
1.不是默认的
2.更快
3.线程不安全
如有两个线程访问同一个属性,会出现无法预料的结果
 对于atomic的属性,系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。比如,线程 A 的 getter 方法运行到一半,线程 B 调用了 setter:那么线程 A 的 getter 还是能得到一个完好无损的对象。而nonatomic就没有这个保证了。所以,nonatomic的速度要比atomic快。
 一般iOS程序中,所有属性都声明为nonatomic。因为在iOS中使用同步锁的开销比较大, 这会带来性能问题。nonatomic的内存管理语义是非原子性的,非原子性的操作本来就是线程不安全,而atomic的操作是原子性的,但并不意味着他就是线程安全的,它会增加正确的几率,能够更好的避免线程错误,但仍旧是不安全的。若要实现“线程安全”的操作,还需采用更为深层的锁定机制才行。
例如:
 一个线程在连续多次读取某个属性值的过程中有别的线程在同时改写该值,那么即便将属性声明为atomic,也还是会读取到不同的属性值。
 还有当线程A进行写操作,这时其他线程的读或者写操作会因为等该操作而等待。当A线程的写操作结束后,B线程进行写操作,然后当A线程需要读操作时,却获得了在B线程的值,这就破坏了线程安全,如果有线程C在A线程读操作之前release了该属性,那么还会导致程序崩溃。
 所以仅仅使用atomic并不会使得线程安全,我们还要为线程添加lock来确保线程的安全。
 因此,iOS程序一般都会使用nonatomic属性。但是在Mac OS X程序时, 使用atomic属性通常都不会有性能瓶颈。

你可能感兴趣的:(atomic 与 nonatomic的区别)