NSString用copy修飾的緣由

一言以蔽之:爲了安全安全

當一個可變字符串(NSMutableString)賦值給一個字符串屬性(不管這個字符串是NSString仍是NSMutableString)atom

若是此屬性是retain修飾的,就是淺拷貝,引用計數加1。賦值後源字符串改變,這個屬性值也跟着改變。spa

若是此屬性是copy修飾的,就是深拷貝,引用計數等於1(由於從堆裏新分配一個內存塊)。賦值後源字符串改變,這個屬性值不會改變。(保證了安全code

假設對象有下面4個屬性:對象

1 @property (retain, nonatomic) NSString *retainStr;
2 @property (copy, nonatomic)   NSString *copyStr;
3 @property (retain, nonatomic) NSMutableString *retainMStr;
4 @property (copy, nonatomic)   NSMutableString *copyMStr;
 1     NSMutableString *mStr = [NSMutableString string];
 2     
 3     [mStr setString:@"我沒變-------"];
 4     self.retainStr   = mStr;  // 淺拷貝,引用計數加1,
 5     NSLog(@"%ld",[self.retainStr retainCount]);// 2
 6     
 7     self.copyStr     = mStr;    // 深拷貝,
 8     NSLog(@"%ld",[self.copyStr retainCount]);// 1
 9     
10     self.retainMStr = mStr;   // 淺拷貝,引用計數加1,
11     NSLog(@"%ld",[self.retainMStr retainCount]);// 3
12     
13     self.copyMStr   = mStr;   // 深拷貝
14     NSLog(@"%ld",[self.copyMStr retainCount]);// 1
15     
16     
17     
18     NSLog(@"retainStr:%@",  self.retainStr);
19     NSLog(@"copyStr:%@",    self.copyStr);
20     NSLog(@"retainMStr:%@", self.retainMStr);
21     NSLog(@"copyMStr:%@",   self.copyMStr);
22     
23     NSLog(@"\n");
24     
25     [mStr setString:@"我變了--------"];
26     
27     NSLog(@"retainStr:%@",  self.retainStr);// 淺拷貝
28     NSLog(@"%ld",[self.retainStr retainCount]);// 3
29     
30     NSLog(@"copyStr:%@",    self.copyStr);// 深拷貝
31     NSLog(@"%ld",[self.copyStr retainCount]);// 1
32     
33     NSLog(@"retainMStr:%@", self.retainMStr);// 淺拷貝
34     NSLog(@"%ld",[self.retainMStr retainCount]);// 3
35     
36     NSLog(@"copyMStr:%@",   self.copyMStr);// 深拷貝
37     NSLog(@"%ld",[self.copyMStr retainCount]);// 1
38     
39     NSLog(@"\n");

 

當一個不可變字符串(NSString)賦值給一個字符串屬性(不管這個字符串是NSString仍是NSMutableString),就不存在安全性問題,都是深拷貝。此時不管retain仍是copy都無所謂。blog

 1     NSString *str = @"我來了";//[[NSString alloc] initWithString:@"我來了"];//兩種方式都同樣。都在常量區
 2     
 3     self.retainStr  = str;
 4     self.copyStr    = str;
 5     self.retainMStr = [str mutableCopy];
 6     self.copyMStr   = [str mutableCopy];
 7     
 8     NSLog(@"retainStr:%@",  self.retainStr);
 9     NSLog(@"copyStr:%@",    self.copyStr);
10     NSLog(@"retainMStr:%@", self.retainMStr);
11     NSLog(@"copyMStr:%@",   self.copyMStr);
12     
13     NSLog(@"\n");
14     
15     str =@"我走了";//[[NSStringalloc] initWithString:@"我走了"];//兩種方式都同樣
16     
17     NSLog(@"retainStr:%@",  self.retainStr);
18     NSLog(@"copyStr:%@",    self.copyStr);
19     NSLog(@"retainMStr:%@", self.retainMStr);
20     NSLog(@"copyMStr:%@",   self.copyMStr);
21     
22     NSLog(@"\n");

打印結果以下:內存

1 2016-06-16 12:24:36.818 OCLession9[5278:90728] retainStr:我來了
2 2016-06-16 12:24:36.819 OCLession9[5278:90728] copyStr:我來了
3 2016-06-16 12:24:36.819 OCLession9[5278:90728] retainMStr:我來了
4 2016-06-16 12:24:36.819 OCLession9[5278:90728] copyMStr:我來了
5 2016-06-16 12:24:36.819 OCLession9[5278:90728] 
6 2016-06-16 12:24:36.819 OCLession9[5278:90728] retainStr:我來了
7 2016-06-16 12:24:36.819 OCLession9[5278:90728] copyStr:我來了
8 2016-06-16 12:24:36.819 OCLession9[5278:90728] retainMStr:我來了
9 2016-06-16 12:24:36.819 OCLession9[5278:90728] copyMStr:我來了
相關文章
相關標籤/搜索