常见的修饰iOS变量属性的atomic与nonatomic关键字,这两个关键字有何作用?
我经常看到的结论是atomic是线程安全的,保证对属性操作的原子性。当然这样付出额外的性能代价,所以atomic并不常用。nonatomic不提供原子性保证,自然也就没有性能方面的代价。所以通常修饰属性用的是nonatomic。但是何时使用atomic呢?atomic的用武之地是什么?apple设计这个关键字有何意义?
顺利成章的,我想到了,也许是在多个线程操作某个属性的时候,使用atomic可以保证原子性操作,从而不需要其他的同步措施,我认为这样的是合理的。并且我一直这么认为,直到有一天我亲自试了一下,发现根本不是这样的,多线程操作某个使用atomic关键字修饰的属性的时候,如果不采取额外的同步措施,结果依然是无法预料的。于是我产生了疑惑,原子性到底是什么意思?
为此,我特意将OC代码通过Clang编译器处理输出了Cpp代码,一共生成了两份代码,一份是atomic关键字修饰,一份是nonatomic关键字修饰,目的就是为了对比生成set方法有何却别。我写了个简单的类如下:
@interface myClass : NSObject
@property(atomic, assign) int age;
@end
这个类生成的Cpp代码如下(这里只列出关键的代码):
static int _I_myClass_age(myClass * self, SEL _cmd) { return (*(int *)((char *)self + OBJC_IVAR_$_myClass$_age)); }
static void _I_myClass_setAge_(myClass * self, SEL _cmd, int age) { (*(int *)((char *)self + OBJC_IVAR_$_myClass$_age)) = age; }
下面是nonatomic关键字修饰的代码:
@interface myClass : NSObject
@property(nonatomic, assign) int age;
@end
clang输出的cpp代码如下:
static int _I_myClass_age(myClass * self, SEL _cmd) { return (*(int *)((char *)self + OBJC_IVAR_$_myClass$_age)); }
static void _I_myClass_setAge_(myClass * self, SEL _cmd, int age) { (*(int *)((char *)self + OBJC_IVAR_$_myClass$_age)) = age; }
通过详细对比,我发现atomic与nonatomic关键字生成的代码基本一致,
也许我找的关键代码片段不对?还是别的原因?反正,在多线程场景下,atomic关键字不能够保证同步访问。如果有人知道这两个关键字的真实意义,还请不吝赐教。