1)一句話介紹
assign: ? ? 簡單的賦值,不改變引用計數(shù)产还。(NSInteger 匹厘、int、 float脐区、 char ...)?
copy: ? ? ? 開辟新的內(nèi)存愈诚,新建一個索引計數(shù)為1的對象,可釋放舊對象。(NSString)
retain: ? ? 是說明該屬性在賦值的時候扰路,先release之前的值,然后再賦新值給屬性倔叼,引用再加1汗唱。
readonly: ? 該對象只能讀取,不能改寫丈攒,只生成getter方法哩罪,不會生成setter方法。
readwrite: ?可讀可寫的對象巡验。
nonatomic:非原子性訪問际插,不加同步,多線程并發(fā)訪問會提高性能显设。
2)換句話說 assign ?and retain 有啥區(qū)別框弛?
現(xiàn)在有這樣一個場景,我分配了一塊內(nèi)存捕捂,并且把它的地址賦值給A指針瑟枫。后來,我希望B指針也可以共享這塊內(nèi)存指攒,于是乎慷妙,我又把A指針(內(nèi)存地址)賦值給了B,這時候咧允悦,A和B就同時擁有這塊內(nèi)存膝擂。
好了,
@property ?(assign, nonatomic) 類型名* A隙弛;
@property? (retain, nonatomic) 類型名* B架馋;
A =[ [ 類型名 alloc] init ] ;? B = A ;
Q:請問當(dāng)A不再需要這塊內(nèi)存,能否直接釋放它驶鹉?
A:? 答案是否定的绩蜻,因為A并不知道B是否還在使用這塊內(nèi)存,如果A釋放了室埋,那么B在使用這塊內(nèi)存的時候會引起程序crash掉办绝。
Q: ?那么如何解決?
A: ?最簡單的一個方法就是使用引用計數(shù)(reference counting)姚淆。我們給那塊內(nèi)存設(shè)一個引用計數(shù)孕蝉,當(dāng)內(nèi)存被分配并且賦值給A時,引用計數(shù)是1腌逢。當(dāng)把A賦值給B時引用計數(shù)增加到2降淮。這時如果A不再使用這塊內(nèi)存,它只需要把引用計數(shù)減1,表明自己不再擁有這塊內(nèi)存佳鳖。B不再使用這塊內(nèi)存時也把引用計數(shù)減1霍殴。當(dāng)引用計數(shù)變?yōu)?的時候,代表該內(nèi)存不再被任何指針?biāo)孟捣裕到y(tǒng)可以把它直接釋放掉来庭。
總的來說:assign就是直接賦值,從而可能引起上面的問題穿挨,當(dāng)數(shù)據(jù)為int, float等原生類型時月弛,可以使用assign。retain使用了引用計數(shù)科盛,retain引起引用計數(shù)加1, release引起引用計數(shù)減1帽衙,當(dāng)引用計數(shù)為0時,dealloc函數(shù)被調(diào)用贞绵,內(nèi)存被回收厉萝。
3)換句話說 copy 到底怎么用?
copy:是在你不希望A和B共享一塊內(nèi)存時會使用到但壮。A和B各自有自己的內(nèi)存冀泻。
NSString、NSArray蜡饵、NSDictionary等等經(jīng)常使用copy關(guān)鍵字弹渔,是因為他們有對應(yīng)的可變類型:NSMutableString、NSMutableArray溯祸、NSMutableDictionary肢专,為確保對象中的屬性值不會無意間變動,應(yīng)該在設(shè)置新屬性值時拷貝一份焦辅,保護其封裝性
block也經(jīng)常使用copy關(guān)鍵字
block 使用 copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內(nèi)部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).
在ARC中寫不寫都行:對于 block 使用 copy 還是 strong 效果是一樣的博杖,但是建議寫上copy,因為這樣顯示告知調(diào)用者“編譯器會自動對 block 進行了 copy 操作”
4)nonatomic 和 atomic 的又怎么說筷登?
【摘自網(wǎng)絡(luò) 侵刪】
atomic:默認是有該屬性的剃根,這個屬性是為了保證程序在多線程情況下,編譯器會自動生成一些互斥加鎖代碼前方,避免該變量的讀寫不同步問題狈醉。
nonatomic:如果該對象無需考慮多線程的情況,請加入這個屬性惠险,這樣會讓編譯器少生成一些互斥加鎖代碼苗傅,可以提高效率。
atomic的意思就是setter/getter這個函數(shù)班巩,是一個原語操作渣慕。如果有多個線程同時調(diào)用setter的話,不會出現(xiàn)某一個線程執(zhí)行完setter全部語句之前,另一個線程開始執(zhí)行setter情況逊桦,相當(dāng)于函數(shù)頭尾加了鎖一樣眨猎,可以保證數(shù)據(jù)的完整性。nonatomic不保證setter/getter的原語行强经,所以你可能會取到不完整的東西宵呛。因此,在多線程的環(huán)境下原子操作是非常必要的夕凝,否則有可能會引起錯誤的結(jié)果
- ?(void)setCurrentImage:(UIImage *)currentImage{
? ? ? ? ? ?NSLock *lock = [[NSLock alloc]init];
? ? ? ? ? ?[lock lock];
? ? ? ? ? if (_currentImage != currentImage) {
? ? ? ? ? ? ? ? ? ? ? [_currentImage release];
? ? ? ? ? ? ? ? ? ? ?_currentImage = [currentImage retain];
? ? ? ? ? ? ? ? ? ?// do something
}
}
可以看出來,用atomic會在多線程的設(shè)值取值時加鎖户秤,中間的執(zhí)行層是處于被保護的一種狀態(tài)码秉,atomic是oc使用的一種線程保護技術(shù),基本上來講鸡号,就是防止在寫入未完成的時候被另外一個線程讀取转砖,造成數(shù)據(jù)錯誤。而這種機制是耗費系統(tǒng)資源的鲸伴,所以在iPhone這種小型設(shè)備上府蔗,如果沒有使用多線程間的通訊編程,那么nonatomic是一個非常好的選擇汞窗。