說說那些年不懂的atomic和nonatomic的區別

首先,明確幾個概念,原子性是什麼?線程安全是什麼?原子性是指一個事物的操作是不可分割的,要麼都發生,要麼都不發生。線程安全是指某個函數、函數庫在多線程環境中被調用時,能夠正確地處理多個線程,使程序功能正確完成。其實意思就是多線程情況下程序的執行順序要有單一性和正確性。

atomic 原子屬性

  • 是默認的
  • 只能說是set/get是安全的,但當進行其他操作的時候,線程並不是完全安全的
  • 會保證 CPU 能在別的線程來訪問這個屬性之前,先執行完當前流程
  • 速度不快,因爲要保證操作整體完成
  • set/get方法內部加了自旋鎖

nonatomic 非原子屬性

  • 不是默認的
  • 線程不安全
  • 如有兩個線程訪問同一個屬性,會出現無法預料的結果
  • 更快
  • set/get方法都不會加鎖

蘋果底層是atomic的setter/getter是自旋鎖(各類鎖可以參考https://www.jianshu.com/p/938d68ed832c

// 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();
   }
   // ...
}

注:atomic是Objc使用的一種線程保護技術,基本上來講是防止在寫未完成的時候另一個線程讀取,造成的數據錯誤。而這種機制是非常耗費系統資源的,所以iPhone這種小型設備上,如果沒有使用多線程間的通訊編程,那麼nonatomic是一個非常好的選擇。而iOS開發中,普遍使用nonatomic也是基於性能這一點。

也可以看看這https://stackoverflow.com/questions/588866/whats-the-difference-between-the-atomic-and-nonatomic-attributes大佬們的理解!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章