關於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)》

相關文章
相關標籤/搜索