在iOS開發中,一般狀況下,一個類可能會有多個屬性,而用來修飾屬性的關鍵字有不少,咱們也會常常遇到下面的面試題:程序員
atomic
和 nonatomic
均可以用來修飾一個屬性,爲何iOS開發中一般用nonatomic
修飾屬性?atomic
是線程安全的嗎(最好結合場景聊聊)?@property (copy) NSString *name;
@property (atomic, copy) NSString *name;
@property (nonatomic, copy) NSString *name;
複製代碼
atomic
),第3行代碼和前2行代碼不一樣。若是是咱們手動實現getter和setter方法,那麼這三行代碼沒有什麼區別由此,能夠得出一個結論,定義屬性時候,atomic
關鍵字爲默認關鍵字。 你們都知道,atomic
關鍵字修飾屬性的性能要比nonatomic
關鍵字修飾屬性的性能要低。因此一般在iOS開發中,定義屬性使用nonatomic
。目的就是爲了提升性能,節省可憐的資源。然而爲何atomic
關鍵字修飾的屬性性能會低呢?面試
當定義一個屬性以後,編譯器會爲自動爲咱們生成帶_
(下劃線)的成員變量以及getter
/setter
方法, 若是使用atomic
修飾屬性,那麼在編譯器爲咱們生成setter/getter方法的時候,會作加鎖的操做,加鎖的目的就是爲了保證存取值的安全性/完整性。安全
場景: 若是使用atomic
修飾屬性值,有A和B兩個線程,A線程對屬性進行賦值,當A線程賦值進行一半的時候,因爲加鎖的緣故,A線程會持有這把鎖,當B線程進行取值操做時候,發現A線程持有鎖,那麼會進行等待,當A線程賦值操做結束後,會放開鎖,那麼B線程持有這把鎖,因此能夠保證B線程必定能夠取到一個完整的值。bash
若是使用nonatomic
修飾屬性值,有A和B兩個線程,A線程對屬性進行賦值,當A線程賦值進行一半的時候,B線程進行取值操做,因爲沒有加鎖,B線程取不到一個完整的值,拿到一個不完整的值去作一些操做就可能會發生意想不到的事情。性能
atomic
並不能保證線程是安全的。atom
場景: 使用atomic
修飾屬性,若是有A、B和C三個線程。其中A和B線程同時對一個屬性進行賦值操做,當賦值一半的時候,C線程進行取值操做,那麼能夠保證C線程必定能夠取到一個完整的值,可是這個值的內容多是A線程賦的值,也多是B線程賦的值,也多是原始值,雖然取得了完整的值,可是這個值不必定是程序員想要的,因此說atomic
並非線程安全的。spa
爲何說atomic
關鍵字是消耗性能的?線程
由於,atomic
底層有加鎖的操做,不管是什麼鎖,內存都會有必定的開銷,性能確定會比nonatomic
低。code
在平時開發的時候,不涉及線程安全的時候,好比一些UI控件必須在主線程操做的,用nonatomic
能夠提升性能。而真正要涉及線程安全,不能只靠編譯器,須要程序員本身控制。內存