概念
关于nonatomic
和atomic
我相信很多人都了解相关的作用,按照字面上理解,nonatomic
是非原子操作,atomic
是原子操作,也可以理解为nonatomic
是线程不安全的,atomic
是线程安全的。
atomic
和nonatomic
区别用来决定编译器生成的getter和setter是否为原子操作。
- atomic 默认是有该属性的,这个属性是为了保证程序在多线程情况下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。
- nonatomic 如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,不用耗费系统资源,可以提高效率。
atomic
atomic
的意思就是setter/getter这个函数,是一个原语操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行完setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁一样,可以保证数据的完整性。
看以下逻辑代码为例:
{lock}
if (property != newValue) {
[property release];
property = [newValue retain];
}
{unlock}
可以看出来,用atomic
会在多线程的设值取值时加锁,中间的执行层是处于被保护的一种状态,atomic
是Objective-C使用的一种线程保护技术,基本上来讲,就是防止在写入未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic
是一个非常好的选择。所以一般iOS程序中,所有属性都声明为nonatomic
。这样做的原因是:在iOS中使用同步锁的开销比较大, 这会带来性能问题。一般情况下并不要求属性必须是“原子的”,因为这并不能保证“线程安全”(thread safety),若要实现“线程安全”的操作,还需采用更为深层的锁定机制才行。
例如:一个线程在连续多次读取某个属性值的过程中有别的线程在同时改写该值,那么即便将属性声明为
atomic
,也还是会读取到不同的属性值。
注意:
atomic
是直接从寄存器上拿数据,而nonatomic
是从内存拿数据
nonatomic
关于nonatomic
是线程不安全的,当有多个线程同时修改属性name
的值的时候,拿到的结果可能不是自己想要的,因为当属性设置nonatomic
的话是允许多个线程是可以同时修改name
的值。
总结
简单来说
atomic
是串行,nonatomic
是并行,但如果要真正实现防止多线程修改某属性的值的时候,单单设置atomic
是不够的,还需要更完善的防止手法