关于IOS 属性atomic(原子性)的理解

抛开语言限制说说什么是原子性:html

原子性是指一个事物的操做是不可分割的,要么都发生,要么都不发生。面试

举个栗子🌰:(摘自某位不肯意透露姓名的大神

银行的转帐业务就是一个原子性的操做。 张三到银行给李四转帐1000元,张三卡里原来有2000元,李四卡里原来也有两千元,那么转帐的步骤应该以下: swift

未命名文件-12.png
若是张三的钱扣完,银行系统瘫痪了,怎么办呢?张三的1000块钱会被会没呢,固然不会。这时候你的钱会退回来。也就是说银行的转帐业务要么成功张三(1000元)李四(3000元),要么不发生张三(2000元)李四(2000元)。

那么回到咱们OC中:(这里讲的是咱们的Objective-c)

看看咱们的atomic和nonatomic,咱们一般的理解是线程安全和非线程安全,我以为这只在语言层面上描述原子性形成的结果。数组

由于atomic描述的是属性赋值,属性赋值中还包含着不少其余操做,如访问对象,赋值等等,natomic是保证这个赋值的整个过程的完整性,而且不受其余线程的干扰,要么成功要么失败。安全

看个问题:为何说atomic有时候没法保证线程安全呢?

先说个人结论: 用atomic修饰后,这个属性的setter、getter方法是线程安全的,可是对于整个对象来讲不必定是线程安全的。学习

1.为何setter、getter方法是线程安全的?

由于在setter和getter赋值取值的时候添加了自旋锁,不懂看这《oc中的线程锁》atom

// getter
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
   // ...
   if (!atomic) return *slot;

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

// setter
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();
   }
   // ...
}
复制代码

2.为何说atomic没办法保证整个对象的线程安全,这里主要看一下网上主流的答案?

1.对于NSArray类型 @property(atomic)NSArray *array咱们用atomic修饰,数组的添加和删除并非线程安全的,这是由于数组比较特殊,咱们要分红两部分考虑,一部分是&array也就是这个数组自己,另外一部分是他所指向的内存部分。atomic限制的只是&array部分,对于它指向的对象没有任何限制。 atomic表示,我TM也很冤啊!!!!spa

2.当线程A进行写操做,这时其余线程的读或者写操做会由于该操做而等待。当A线程的写操做结束后,B线程进行写操做,而后当A线程须要读操做时,却得到了在B线程中的值,这就破坏了线程安全,若是有线程C在A线程读操做前release了该属性,那么还会致使程序崩溃。因此仅仅使用atomic并不会使得线程安全,咱们还要为线程添加lock来确保线程的安全。 我的以为这个就有点杠精的意味了,atomic还要管到你方法外面去了?????不过面试人家问你还要这么答,要严谨!!,.net

我的理解有问题你们多多提出,讨论中才能学习。线程

好文推荐: 《iOS atomic 对象是线程不安全的缘由以及与 nonatomic 的区别》(这个名字很奇怪😄,说白了不安全是由OC对象的引用特性形成的,能够看下) 《事务四大特征:原子性,一致性,隔离性和持久性(ACID)》

相关文章
相关标签/搜索