一、定義
weak:簡單來講是弱引用患雇。引用計數(shù)器不會加一,?只能修飾對象 宇挫,對象釋放后苛吱,指針為nil,對nil 訪問不會造成崩潰器瘪。通常用于解決循環(huán)引用問題翠储。適用于delegate和block
Strong:強(qiáng)引用。MRC下引用計數(shù)器會加一橡疼,默認(rèn)所有實(shí)例變量和局部變量都是Strong指針
Copy:也是強(qiáng)引用援所,但是引用計數(shù)器不會加一。
Assign:assign一般用于基本數(shù)據(jù)類型欣除,無引用計數(shù)器住拭。這種類型是放在棧中的,由系統(tǒng)來控制創(chuàng)建和銷毀。也可以用于對象滔岳,但是用于對象并不會引用計數(shù)杠娱,如果你用它修飾對象,那么他會放在堆中谱煤,由我們自己來控制銷毀摊求,而他又是弱類型。所以很容易造成野指針和內(nèi)存泄露問題刘离。對象被莫名釋放室叉,那么就會崩潰。
二硫惕、關(guān)鍵字含義
copy
復(fù)制內(nèi)容(深復(fù)制)茧痕,如果調(diào)用copy的是數(shù)組,則為指針復(fù)制(淺復(fù)制)疲憋,僅僅復(fù)制子元素的指針凿渊。
@property? (nonatomic,copy)NSString? *title;
@property (nonatomic, copy) NSMutableArray *myArray;//not recommended
assign
對基礎(chǔ)數(shù)據(jù)類型(NSInteger,CGFloat)和C數(shù)據(jù)類型(int,? float, double, char等)
@property? (nonatomic, assign) int n;
@property (nonatomic, assign) BOOL isOK;
@property (nonatomic,? assign)? CGFloat scalarFloat;
@property (nonatomic,? assign)? CGPoint scalarStruct;
strong
相當(dāng)于retain缚柳。
Strong在ARC環(huán)境為默認(rèn)屬性類型埃脏。
@property? (nonatomic,readwrite,strong)NSString *title;
@property (strong, nonatomic) UIViewController *viewController;
@property (nonatomic,? strong) id? childObject;
retain
NSObject及其子類。
Release舊值秋忙,retain新值彩掐。
Retain是指針復(fù)制(淺復(fù)制),引用計數(shù)加1灰追,而不會導(dǎo)致內(nèi)容被復(fù)制堵幽。
@property? (nonatomic, retain)UIColor *myColor;
weak
取代之前的assign,對象銷毀之后會自動置為nil弹澎,防止野指針朴下。
Assign不能自動置為nil,需要手動置為nil苦蒿。
Delegate基本總是使用weak殴胧,以防止循環(huán)引用。特殊情況是佩迟,希望在dealloc中調(diào)用delegate的某些方法進(jìn)行釋放团滥,此時如果使用weak將引起異常,因?yàn)榇藭r已經(jīng)是nil了报强,那么采用assign更為合適灸姊。
@property? (weak, nonatomic) IBOutlet UIButton *myButton;//處于最頂層的IBOutlet應(yīng)該為strong
@property (nonatomic,? weak) id? parentObject;
@property(nonatomic,readwrite,weak) id?? delegate;
@property (nonatomic,? weak) NSObject?? *delegate;
readonly
此標(biāo)記說明屬性是只讀的,默認(rèn)的標(biāo)記是讀寫秉溉,如果你指定了只讀力惯,在@implementation中只需要一個讀取器碗誉。或者如果你使用@synthesize關(guān)鍵字夯膀,也是有讀取器方法被解析诗充。而且如果你試圖使用點(diǎn)操作符為屬性賦值,你將得到一個編譯錯誤诱建。
readwrite
此標(biāo)記說明屬性會被當(dāng)成讀寫的蝴蜓,這也是默認(rèn)屬性。設(shè)置器和讀取器都需要在@implementation中實(shí)現(xiàn)俺猿。如果使用@synthesize關(guān)鍵字茎匠,讀取器和設(shè)置器都會被解析。
三押袍、關(guān)鍵字使用區(qū)別
copy與retain
1诵冒、copy其實(shí)是建立了一個相同的對象,而retain不是谊惭;
2汽馋、copy是內(nèi)容拷貝,retain是指針拷貝圈盔;
3豹芯、copy是內(nèi)容的拷貝 ,對于像NSString,的確是這樣,但是如果copy的是一個NSArray呢?這時只是copy了指向array中相對應(yīng)元素的指針.這便是所謂的"淺復(fù)制".
4驱敲、copy的情況:NSString *newPt = [pt copy];
此時會在堆上重新開辟一段內(nèi)存存放@"abc" 比如0X1122 內(nèi)容為@"abc 同時會在棧上為newPt分配空間 比如地址:0Xaacc 內(nèi)容為0X1122 因此retainCount增加1供newPt來管理0X1122這段內(nèi)存铁蹈;
assign與retain
1、assign: 簡單賦值众眨,不更改索引計數(shù)握牧;
2、assign的情況:NSString *newPt = [pt assing];
此時newPt和pt完全相同 地址都是0Xaaaa 內(nèi)容為0X1111 即newPt只是pt的別名娩梨,對任何一個操作就等于對另一個操作沿腰, 因此retainCount不需要增加;
3狈定、assign就是直接賦值颂龙;
4、retain使用了引用計數(shù)掸冤,retain引起引用計數(shù)加1, release引起引用計數(shù)減1厘托,當(dāng)引用計數(shù)為0時友雳,dealloc函數(shù)被調(diào)用稿湿,內(nèi)存被回收;
5押赊、retain的情況:NSString *newPt = [pt retain];
此時newPt的地址不再為0Xaaaa饺藤,可能為0Xaabb 但是內(nèi)容依然為0X1111包斑。 因此newPt 和 pt 都可以管理"abc"所在的內(nèi)存,因此 retainCount需要增加1涕俗;
readonly與 readwrite
readonly:只產(chǎn)生簡單的getter,沒有setter罗丰。
readwrite:同時產(chǎn)生setter\getter方法。
nonatomic再姑,atomic
1萌抵、非原子性訪問,對屬性賦值的時候不加鎖元镀,多線程并發(fā)訪問會提高性能绍填。如果不加此屬性,則默認(rèn)是兩個訪問方法都為原子型事務(wù)訪問栖疑;
weak and strong property (強(qiáng)引用和弱引用的區(qū)別):
2讨永,置成員變量的@property屬性時,默認(rèn)為atomic遇革,提供多線程安全卿闹。在多線程環(huán)境下,原子操作是必要的萝快,否則有可能引起錯誤的結(jié)果
atomic的意思就是setter/getter這個函數(shù)锻霎,是一個原語操作。如果有多個線程同時調(diào)用setter的話杠巡,不會出現(xiàn)某一個線程執(zhí)行完setter全部語句之前量窘,另一個線程開始執(zhí)行setter情況,相當(dāng)于函數(shù)頭尾加了鎖一樣氢拥,可以保證數(shù)據(jù)的完整性蚌铜。nonatomic不保證setter/getter的原語行,所以你可能會取到不完整的東西嫩海。因此冬殃,在多線程的環(huán)境下原子操作是非常必要的,否則有可能會引起錯誤的結(jié)果叁怪。
比如setter函數(shù)里面改變兩個成員變量审葬,如果你用nonatomic的話,getter可能會取到只更改了其中一個變量時候的狀態(tài)奕谭,這樣取到的東西會有問題涣觉,就是不完整的。當(dāng)然如果不需要多線程支持的話血柳,用nonatomic就夠了官册,因?yàn)椴簧婕暗骄€程鎖的操作,所以它執(zhí)行率相對快些难捌。
weak 和 strong
1膝宁、weak 和 strong 屬性只有在你打開ARC時才會被要求使用鸦难,這時你是不能使用retain release autorelease 操作的,因?yàn)锳RC會自動為你做好這些操作员淫,但是你需要在對象屬性上使用weak 和strong,其中strong就相當(dāng)于retain屬性合蔽,而weak相當(dāng)于assign。
2介返、只有一種情況你需要使用weak(默認(rèn)是strong)拴事,就是為了避免retain cycles(就是父類中含有子類{父類retain了子類},子類中又調(diào)用了父類{子類又retain了父類}圣蝎,這樣都無法release)
3挤聘、聲明為weak的指針,指針指向的地址一旦被釋放捅彻,這些指針都將被賦值為nil组去。這樣的好處能有效的防止野指針。
三步淹、strong,weak,copy 具體用法
1.具體一點(diǎn):IBOutlet可以為weak从隆,NSString為copy,Delegate一般為weak缭裆,其他的看情況键闺。一般來說,類 “內(nèi)部”的屬性設(shè)置為strong澈驼,類“外部”的屬性設(shè)置為weak辛燥。說到底就是一個歸屬權(quán)的問題。小心出現(xiàn)循環(huán)引用導(dǎo)致內(nèi)存無法釋放缝其。
2.不用ARC的話就會看到很多retian挎塌。
3.如果你寫了@synthesize abc = _abc;的話内边,系統(tǒng)自動幫你聲明了一個_abc的實(shí)例變量榴都。
使用assign: 對基礎(chǔ)數(shù)據(jù)類型 (NSInteger)和C數(shù)據(jù)類型(int, float, double, char,等)
使用copy: 對NSString
使用retain: 對其他NSObject和其子類
assign:默認(rèn)類型,setter方法直接賦值,而不進(jìn)行retain操作
retain:setter方法對參數(shù)進(jìn)行release舊值漠其,再retain新值嘴高。
copy:setter方法進(jìn)行Copy操作,與retain一樣