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