最近找工作,一直想搞明白nonatomic和atomic的區(qū)別,無(wú)意間看到了一些資料,簡(jiǎn)單的做一下記錄
atomic的意思就是setter/getter這兩個(gè)函數(shù)的一個(gè)原語(yǔ)操作。如果有多個(gè)線程同時(shí)調(diào)用setter的話(huà),不會(huì)出現(xiàn)某一個(gè)線程執(zhí)行
setter全部語(yǔ)句之前,另一個(gè)線程開(kāi)始執(zhí)行setter情況,相當(dāng)于函數(shù)頭尾加了鎖一樣。
nonatomic不保證setter/getter的原語(yǔ)行,所以你可能會(huì)取到不完整的東西。
比如setter函數(shù)里面改變兩個(gè)成員變量,如果你用nonatomic的話(huà),getter可能會(huì)取到只更改了其中一個(gè)變量時(shí)候的狀態(tài)。
atomic是線程安全的,nonatomic是線程不安全的。如果只是單線程操作的話(huà)用nonatomic最好,因?yàn)楹笳咝矢咭恍?/p>
atomic是線程安全的,nonatomic是線程不安全的。如果只是單線程操作的話(huà)用nonatomic最好,因?yàn)楹笳咝矢咭恍?/p>
assign
對(duì)基礎(chǔ)數(shù)據(jù)類(lèi)型 (NSInteger,CGFloat)和C數(shù)據(jù)類(lèi)型(int, float, double, char)等等。
此標(biāo)記說(shuō)明設(shè)置器直接進(jìn)行賦值,這也是默認(rèn)值。在
使用垃圾收集的應(yīng)用程序中,如果你要一個(gè)屬性使用assign,且這個(gè)類(lèi)符合NSCopying協(xié)
議,你就要明確指出這個(gè)標(biāo)記,而不是簡(jiǎn)單地使用默認(rèn)值,否則的話(huà),你將得到一個(gè)編譯警告。這再次向編譯器說(shuō)明你確實(shí)需要賦值,即使它是
可拷貝的。
retain
對(duì)其他NSObject和其子類(lèi)對(duì)參數(shù)進(jìn)行release舊值,再retain新值
指定retain會(huì)在賦值時(shí)喚醒傳入值的retain消息。此屬性只能用于Objective-C對(duì)象類(lèi)型,而不能用于Core Foundation對(duì)象。(原因很明顯,retain會(huì)增加對(duì)象的引用計(jì)數(shù),而基本數(shù)據(jù)類(lèi)型或者Core Foundation對(duì)象都沒(méi)有引用計(jì)數(shù)——譯者注)。
注意: 把對(duì)象添加到數(shù)組中時(shí),引用計(jì)數(shù)將增加對(duì)象的引用次數(shù)+1。
copy
對(duì)NSString 它指出,在賦值時(shí)使用傳入值的一份拷貝。拷貝工作由copy方法執(zhí)行,此屬性只對(duì)那些實(shí)行了NSCopying協(xié)議的對(duì)象類(lèi)型有效。更深入的討論,請(qǐng)參考“復(fù)制”部分。
copy與retain:
Copy其實(shí)是建立了一個(gè)相同的對(duì)象,而retain不是:
1.比如一個(gè)NSString 對(duì)象,地址為0×1111 ,內(nèi)容為@”STR”,Copy
到另外一個(gè)NSString 之后,地址為0×2222 ,內(nèi)容相同。
2.新的對(duì)象retain為1,舊有對(duì)象沒(méi)有變化retain
到另外一個(gè)NSString 之后,地址相同(建立一個(gè)指針,指針拷貝),內(nèi)容當(dāng)然相同,這個(gè)對(duì)象的retain值+1。
總結(jié):retain 是指針拷貝,copy 是內(nèi)容拷貝。
assign與retain:
1.
接觸過(guò)C,那么假設(shè)你用malloc分配了一塊內(nèi)存,并且把它的地址賦值給了指針a,后來(lái)你希望指針b也共享這塊內(nèi)存,于是你又把a(bǔ)賦值給
(assign)了b。此時(shí)a和b指向同一塊內(nèi)存,請(qǐng)問(wèn)當(dāng)a不再需要這塊內(nèi)存,能否直接釋放它?答案是否定的,因?yàn)閍并不知道b是否還在使用這塊內(nèi)存,如
果a釋放了,那么b在使用這塊內(nèi)存的時(shí)候會(huì)引起程序crash掉。
2.
了解到1中assign的問(wèn)題,那么如何解決?最簡(jiǎn)單的一個(gè)方法就是使用引用計(jì)數(shù)(reference
counting),還是上面的那個(gè)例子,我們給那塊內(nèi)存設(shè)一個(gè)引用計(jì)數(shù),當(dāng)內(nèi)存被分配并且賦值給a時(shí),引用計(jì)數(shù)是1。當(dāng)把a(bǔ)賦值給b時(shí)引用計(jì)數(shù)增加到
2。這時(shí)如果a不再使用這塊內(nèi)存,它只需要把引用計(jì)數(shù)減1,表明自己不再擁有這塊內(nèi)存。b不再使用這塊內(nèi)存時(shí)也把引用計(jì)數(shù)減1。當(dāng)引用計(jì)數(shù)變?yōu)?的時(shí)候,
代表該內(nèi)存不再被任何指針?biāo)?,系統(tǒng)可以把它直接釋放掉。
總結(jié):上面兩點(diǎn)其實(shí)就是assign和retain的區(qū)別,assign就是直接賦值,從而可能引起1中的問(wèn)題,當(dāng)數(shù)據(jù)為int, float等原生類(lèi)型時(shí),可以使用assign。retain就如2中所述,使用了引用計(jì)數(shù),retain引起引用計(jì)數(shù)加1,
release引起引用計(jì)數(shù)減1,當(dāng)引用計(jì)數(shù)為0時(shí),dealloc函數(shù)被調(diào)用,內(nèi)存被回收。