前言
atomic/nonatomic 是屬性修飾符之一,atomic 代表原子性,nonatomic 代表非原子性;
原子性是防止方法調(diào)用到一半其它操作再次進(jìn)入該方法,導(dǎo)致出現(xiàn)異常情況。
atomic 和 nonatomic 區(qū)別以及實(shí)現(xiàn)
首先我們知道 atomic 代表原子性,nonatomic 代表非原子性;用這兩個(gè)修飾符來修飾屬性,區(qū)別主要在于屬性的 getter/setter 方法:atomic 會(huì)對(duì) setter 方法進(jìn)行加鎖,nonatomic 不會(huì)對(duì) setter 方法加鎖。
atomic 修飾的屬性,在 setter 方法中使用@synchronized加鎖來確保原子操作,但是@synchronized相比于其它類型的鎖,性能是最低效的,因?yàn)槌思渔i之外,額外還會(huì)設(shè)置異常處理機(jī)制,性能消耗較大。這里就是為什么平時(shí)開發(fā)中很少使用 atomic 來修飾屬性。
atomic 與 nonatomic 在 getter/setter 方法區(qū)別如下:

atomic 不保證線程安全
atomic 只會(huì)保證 setter/getter 方法是原子操作的,防止方法調(diào)用到一半其它操作再次進(jìn)入該方法,導(dǎo)致出現(xiàn)異常情況。即原子性保證你訪問的時(shí)候給你返回一個(gè)完好無損的對(duì)象,但是不會(huì)保證線程安全,這里有個(gè)經(jīng)典的例子:
如果線程 A 調(diào)了 getter,與此同時(shí)線程 B 、線程 C 都調(diào)了 setter——那最后線程 A get 到的值,有3種可能:可能是 B、C set之前原始的值,也可能是 B set的值,也可能是 C set的值。同時(shí),最終這個(gè)屬性的值,可能是 B set的值,也有可能是 C set的值。所以atomic可并不能保證對(duì)象的線程安全。
這個(gè)問題其實(shí)包括兩個(gè)塊內(nèi)存,一個(gè)是棧區(qū)指針的內(nèi)存A,一個(gè)是堆區(qū)對(duì)象占用的內(nèi)存B。
atomic 只是對(duì)屬性的 getter/setter 方法加自旋鎖,也就是對(duì)A加鎖,這樣可以保證A是線程安全的。這樣并沒有對(duì)B做任何處理,所以B不是線程安全的。
如果一個(gè)對(duì)象的改變不是直接調(diào)用 getter/setter 方法,而是直接對(duì)對(duì)象內(nèi)部屬性修改、字符串拼接、數(shù)組增加和移除元素等操作,就不能保證這個(gè)對(duì)象是線程安全的。