您的位置:首页 > 移动开发 > IOS开发

iOS atomic 原子性

2019-03-07 09:35 92 查看

atomic 原子性

atomic
用于保证属性
setter、getter
的原子性操作,相当于在
getter
setter
内部加了线程同步锁

源码在

objc4
objc-accessors.mm
里面可以看到

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
if (offset == 0) {
object_setClass(self, newValue);
return;
}

id oldValue;
id *slot = (id*) ((char*)self + offset);

if (copy) {
newValue = [newValue copyWithZone:nil];
} else if (mutableCopy) {
newValue = [newValue mutableCopyWithZone:nil];
} else {
if (*slot == newValue) return;
newValue = objc_retain(newValue);
}

if (!atomic) {
oldValue = *slot;
*slot = newValue;
} else {
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
oldValue = *slot;
*slot = newValue;
slotlock.unlock();
}

objc_release(oldValue);
}

id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
if (offset == 0) {
return object_getClass(self);
}

// Retain release world
id *slot = (id*) ((char*)self + offset);
if (!atomic) return *slot;

// Atomic retain release world
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
id value = objc_retain(*slot);
slotlock.unlock();

// for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.
return objc_autoreleaseReturnValue(value);
}

它并不能保证使用属性的过程是线程安全的
例如属性为一个数组,对数组进行set、get方法的调用是线程安全的
但是往数组中添加元素的过程不是线程安全的,需要另外加锁

Person *p = [[Person alloc] init];

for (int i = 0; i < 10; i++) {
dispatch_async(NULL, ^{
// 加锁 set
p.data = [NSMutableArray array];
// 解锁
});
}

// 加锁 get
NSMutableArray *array = p.data;
// 解锁

// 加锁 添加元素
[array addObject:@"1"];
[array addObject:@"2"];
[array addObject:@"3"];
// 解锁

atomic
比较耗费性能,在iOS中使用比较少,在mac编程中使用较多。
iOS一般对同一个属性的读写都在同一线程,且操作比较频繁。因此使用
nonatomic

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: