原文位址:http://my.oschina.net/openlab/blog/89354
舉個例子:
NSString *houseOfMM = [[NSString alloc] initWithString:'裝梵幾的三室兩廳'];
上面一段代碼會執行以下兩個動作:
1 在堆上配置設定一段記憶體用來存儲@' 裝梵幾的三室兩廳 ' ,比如:記憶體位址為 0X1111 内容為 ' 裝梵幾的三室兩廳' ,
2 在棧上配置設定一段記憶體用來存儲 houseForWife ,比如:位址為 0XAAAA 内容自然為 0X1111
下面分别看下(assign,retain,copy):
1.assign的情況: NSString * myHouse = [ houseOfMM assign ];
此時 myHouse 和 houseOfMM 完全相同,位址都是 0XAAAA ,内容為 0X1111 ,即 myHouse 隻是 houseOfMM 的别名,對任何一個操作就等于對另一個操作。是以 retainCount 不需要增加.(同進同出,關系好,一把鑰匙,給我拿着)
2.retain的情況: NSString * myHouse = [ houseOfMM retain ];
此時 myHouse 的位址不再為 0XAAAA ,可能為 0XAABB ,但是内容依然為 0X1111 .是以 myHouse 和 houseOfMM 都可以管理' 裝梵幾的三室兩廳 '所在的記憶體。是以 retainCount 需要增加1.(有些獨立,各自進出,兩把鑰匙)
3.copy的情況: NSString * myHouse = [ houseOfMM copy ];
此時會在堆上重新開辟一段記憶體存放@'裝梵幾的三室兩廳',比如0X1122,内容為@'裝梵幾的三室兩廳',同時會在棧上為myHouse配置設定空間,比如位址:0XAACC,内容為0X1122,是以retainCount增加1供myHouse來管理0X1122這段記憶體.(兩套@'裝梵幾的三室兩廳',條件好,分居了,房子一人一套,是以鑰匙一人一把。)
什麼時候用assign,當然是破房子,簡裝的房子拉
基礎類型(簡單類型,原子類型):NSInteger,CGPoint,CGFloat,C資料類型(int,float,double,char等)
什麼時候用copy
含有可深拷貝的mutable子類的類,如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString
(可深度拷貝的房子)
但是NSMutableArray這樣的不可以,Mutable的不能用copy,不然初始化會有問題。切記
什麼時候用retain
其他NSObject和其子類對象好嘛 (大多數)
來源于:http://zhidao.baidu.com/link?url=ghacWu7Us0aPRA7PCjh7AsUbU-j8tguVDMda45WOn19_DfzdbWUwi432umsM3OjtpoLTVo_cQf1BTPPot5WOht00lBBfDjVl78qYeWll-ia
copy:建立一個索引計數為1的對象,然後釋放舊對象
@property(nonatomic,assign)NSString *title;
什麼是retain,assgin,copy之間的差別?
assign:簡單指派不更改索引計數(reference count)。
copy:建立一個索引計數為1的對象,然後釋放舊對象。
retain:釋放舊的對象,将舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1
retain的實際文法為:
- (void)setName:(NSString *)newName {
if (name != newName) {
[name release];
name = [newName retain];
// name’s retain count has been bumped up by 1
}
}
說了那麼麻煩,其實接下來的話最重要:
使用assign: 對基礎資料類型 (NSInteger,CGFloat)和C資料類型(int, float, double, char, 等等)
使用copy: 對NSString
使用retain: 對其他NSObject和其子類
nonatomic關鍵字:
atomic是Objc使用的一種線程保護技術,基本上來講,是防止在寫未完成的時候被另外一個線程讀取,造成資料錯誤。而這種機制是耗費系統資源的,是以在iPhone這種小型裝置上,如果沒有使用多線程間的通訊程式設計,那麼nonatomic是一個非常好的選擇。
再轉一篇:http://bbs.itheima.com/thread-145753-1-1.html
記得看李明傑老師的視訊,老師說過,凡是nsstring,就用copy,定義一個模型對象,就用strong,隻是指派的,例如int、double、char 以及CGRect類似的就用assign。
自己的筆記如下~
這些關鍵字基本上是針對屬性的set方法。
當用copy時,set方法會先release舊值,再copy一個新的對象,reference count 為1(減少了對上下文的依賴);當用assign,直接指派,無retain操作。當用retain,release舊值,retain新值;
而strong與weak的差別
strong類似于retain,會将對象的引用計數器+1,配置設定記憶體位址。
weak類似于指針,隻是單純的指向某個位址,但是本身并未配置設定記憶體位址。當指向的位址被銷毀時,該指針會自動nil。
例子:
1. @synthesize string1;
2. @synthesize string2;
再來猜一下,下面輸出是什麼?
1. self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];
2. self.string2 = self.string1;
3. self.string1 = nil;
4. NSLog(@"String 2 = %@", self.string2);
結果是:String 2 = null
分析一下,由于self.string1與self.string2指向同一位址,且string2沒有retain記憶體位址,而 self.string1=nil釋放了記憶體,是以string1為nil。聲明為weak的指針,指針指向的位址一旦被釋放,這些指針都将被指派為 nil。這樣的好處能有效的防止野指針。在c/c++開發過程中,指針的空間釋放了後,都要将指針賦為NULL. 在這兒用weak關鍵字做了這一步。