assign,copy,retain之間的區別
阿新 • • 發佈:2019-02-14
copy: 建立一個索引計數為1的物件,然後釋放舊物件
retain:釋放舊的物件,將舊物件的值賦予輸入物件,再提高輸入物件的索引計數為1
Copy其實是建立了一個相同的物件,而retain不是:
比如一個NSString物件,地址為0×1111,內容為@”STR”
Copy到另外一個NSString之後,地址為0×2222,內容相同,新的物件retain為1,舊有物件沒有變化
retain到另外一個NSString之後,地址相同(建立一個指標,指標拷貝),內容當然相同,這個物件的retain值+1
也就是說,retain是指標拷貝,copy是內容拷貝。
一般情況下:
使用assign: 對基礎資料型別 (NSInteger,CGFloat)和C資料型別(int, float, double, char, 等等)
使用copy: 對NSString
2.retain的情況:NSString * newStr = [str retain];
此時newStr的地址不再為0XAAAA,可能為0XAABB,但是內容依然為0X1111.因此newStr和str都可以管理'abc'所在的記憶體。因此 retainCount需要增加1.
3.copy的情況:NSString * newStr = [str copy];
此時會在堆上重新開闢一段記憶體存放@'abc',比如0X1122,內容為@'abc,同時會在棧上為newStr分配空間,比如地址:0XAACC,內容為0X1122,因此retainCount增加1供newStr來管理0X1122這段記憶體.
retain:釋放舊的物件,將舊物件的值賦予輸入物件,再提高輸入物件的索引計數為1
Copy其實是建立了一個相同的物件,而retain不是:
比如一個NSString物件,地址為0×1111,內容為@”STR”
Copy到另外一個NSString之後,地址為0×2222,內容相同,新的物件retain為1,舊有物件沒有變化
retain到另外一個NSString之後,地址相同(建立一個指標,指標拷貝),內容當然相同,這個物件的retain值+1
也就是說,retain是指標拷貝,copy是內容拷貝。
一般情況下:
使用assign: 對基礎資料型別 (NSInteger,CGFloat)和C資料型別(int, float, double, char, 等等)
使用copy: 對NSString
使用retain: 對其他NSObject和其子類
舉個例子: NSString *str = [[NSString alloc] initWithString:@'abc']; 上面一段程式碼會執行以下兩個動作: 1 在堆上分配一段記憶體用來儲存@'abc' ,比如:記憶體地址為0X1111 內容為 'abc' 2 在棧上分配一段記憶體用來儲存str,比如:地址為0XAAAA 內容自然為0X1111 下面分別看下(assign,retain,copy): 1.assign的情況:NSString *newStr = [str assign]; 此時newStr和str完全相同,地址都是0XAAAA ,內容為0X1111 ,即newStr只是str的別名,對任何一個操作就等於對另一個操作。因此retainCount不需要增加.3、示例:環境是在不選擇ARC的環境下
新建Person類,使他繼承與NSObject,在.m檔案中實現dealloc方法:- - (void) dealloc
- {
- NSLog (@"dealloc called. Bye Bye.");
- [super dealloc];
- }
- Person *person = [[Person alloc] init];
- NSLog(@"物件person的retainCount: %d", [person retainCount]);
物件person的retainCount: 1
我們增加1
- Person *person = [[Person alloc] init];
- NSLog(@"物件person的retainCount: %d",[person retainCount] );
- [person retain];
- NSLog(@"物件person的retainCount: %d", [person retainCount]);
列印結果:
物件person的retainCount: 1
物件person的retainCount: 2
和傳說的一樣,retainCount增加了。可以有在release時,減少到1時就不再減 了
- Person *person = [[Person alloc] init];
- NSLog(@"物件person的retainCount: %d",[person retainCount] );
- [person retain];
- NSLog(@"物件person的retainCount: %d", [person retainCount]);
- [person release];
- [person release];
- NSLog(@"物件person的retainCount: %d", [person retainCount]);
- 2012-07-05 16:05:29.830 ObjectiveCTest[2847:f803] 物件person的retainCount: 1
- 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] 物件person的retainCount: 2
- 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] dealloc called. Bye Bye.
- 2012-07-05 16:05:29.832 ObjectiveCTest[2847:f803] 物件person的retainCount: 1