1、atomic简介
atomic用于保证属性setter、getter的原子性操作,相当于在getter和setter内部加了线程同步的锁,可以通过 objc源码 中的objc-accessors.mm文件查看:
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy){......if (!atomic) {// 非原子oldValue = *slot;*slot = newValue;} else {// 原子spinlock_t& slotlock = PropertyLocks[slot];// 加锁slotlock.lock();oldValue = *slot;*slot = newValue;// 解锁slotlock.unlock();}......}
在执行属性的set方法时,如果是非原子就直接赋值,如果是原子就会进行加锁解锁操作。属性的get方法原理相同:
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {if (offset == 0) {return object_getClass(self);}id *slot = (id*) ((char*)self + offset);if (!atomic) return *slot; //非原子:直接返回// 原子:加锁、解锁spinlock_t& slotlock = PropertyLocks[slot];slotlock.lock();id value = objc_retain(*slot);slotlock.unlock();return objc_autoreleaseReturnValue(value);}
2、atomic特点
2.1、不能保证属性使用过程的线程安全
比如person有一个data属性,外部可以不通过set/get方法去修改data,所以data也不是完全安全的。
Person *person = [[Person alloc] init];// 线程安全,调用set/get方法person.data = [[NSMutableArray alloc] init];// 线程不安全,直接修改属性内容[person.data addObject:@"1"];[person.data addObject:@"2"];[person.data addObject:@"3"];
2.2、性能消耗比较大
对象属性的调用频率比较大,如果使用automic会频繁创建自旋锁,多内存和CPU消耗多比较大。所以iOS中一般不使用aotomic,如果要保证同步可以再需要同步的地方手动加锁。
