首先聲明
@property (retain,nonatomic) NSString *rStr;
@property (copy, nonatomic) NSString *cStr;
@property (retain,nonatomic) NSString *rStr2;
@property (copy, nonatomic) NSString *cStr2;
對(duì)NSMutableString的對(duì)象賦值
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
self.rStr = mStr;
self.cStr = mStr;
/*
第一個(gè)%p:是打印的指向mStr指針的地址
第二個(gè)%p是打印的指向mStr指針的指針的地址
相當(dāng)于C中 * 和**的區(qū)別
*/
NSLog(@"mStr:%p,%p", mStr,&mStr); //mStr:0x7fd513413f80,0x7fff522d9898
NSLog(@"retainStr:%p,%p", _rStr, &_rStr); //retainStr:0x7fd513413f80,0x7fd513618428
NSLog(@"copyStr:%p,%p", _cStr, &_cStr); //copyStr:0xa000000006362613,0x7fd513618430
- 理解 把NSMutableString對(duì)象mStr分別賦值給屬性為retain的_rStr 和 屬性為copy的_cStr而姐。從打印的結(jié)果可以看出剑梳,賦值以后较性,屬性為retain的對(duì)象的
指針地址
和原對(duì)象是一樣侠鳄,指針的指針地址
不一樣仔引,所以可以說(shuō)是同一個(gè)對(duì)象咱筛。這也叫做淺拷貝
胚嘲。而屬性為copy的對(duì)象和原對(duì)象指針
不一樣。就意味著產(chǎn)生了一個(gè)新的對(duì)象强胰。所以叫做深拷貝
[mStr appendString:@"de"];
NSLog(@"retainStr:%@", _rStr); //retainStr:abcde
NSLog(@"copyStr:%@", _cStr); //copyStr:abc
- 對(duì)源頭是NSMutableString的字符串舱沧,retain僅僅是指針引用,增加了引用計(jì)數(shù)器哪廓,這樣源頭改變的時(shí)候狗唉,用這種retain方式聲明的變量(無(wú)論被賦值的變量是可變的還是不可變的),它也會(huì)跟著改變;而copy聲明的變量涡真,它不會(huì)跟著源頭改變分俯,它實(shí)際上是
深拷貝
。
對(duì)對(duì)NSString的對(duì)象賦值
NSString *noString = [NSString stringWithFormat:@"123"];
self.rStr2 = noString;
self.cStr2 = noString;
NSLog(@"mStr:%p,%p", noString,&noString); //mStr:0xa000000003332313,0x7fff522d9890
NSLog(@"retainStr:%p,%p", _rStr2, &_rStr2); //retainStr:0xa000000003332313,0x7fd513618438
NSLog(@"copyStr:%p,%p", _cStr2, &_cStr2); //copyStr:0xa000000003332313,0x7fd513618440
對(duì)源頭是NSString的字符串哆料,無(wú)論是retain聲明的變量還是copy聲明的變量缸剪,當(dāng)?shù)诙卧搭^的字符串重新指向其它的地方的時(shí)候,它還是指向原來(lái)的最初的那個(gè)位置东亦,也就是說(shuō)其實(shí)二者都是指針引用杏节,也就是
淺拷貝
。注意 上面的情況是針對(duì)于當(dāng)把NSMutableString賦值給NSString的時(shí)候典阵,才會(huì)有不同奋渔,如果是賦值是NSString對(duì)象,那么使用copy還是strong壮啊,結(jié)果都是一樣的嫉鲸,因?yàn)镹SString對(duì)象根本就不能改變自身的值,他是不可變的歹啼。
其實(shí)說(shuō)白了玄渗,對(duì)字符串為啥要用這兩種方式?我覺(jué)得還是一個(gè)安全問(wèn)題狸眼,比如聲明的一個(gè)
NSString *str
變量藤树,然后把一個(gè)NSMutableString *mStr
變量的賦值給它了,如果要求str跟著mStr變化拓萌,那么就用retain;如果str不能跟著mStr一起變化岁钓,那就用copy。而對(duì)于要把NSString類(lèi)型的字符串賦值給str,那兩都沒(méi)啥區(qū)別甜紫。不會(huì)影響安全性降宅,內(nèi)存管理也一樣。所以囚霸,在聲明NSString屬性時(shí),到底是選擇strong還是copy激才,可以根據(jù)實(shí)際情況來(lái)定拓型。不過(guò),一般我們將對(duì)象聲明為NSString時(shí)瘸恼,都不希望它改變劣挫,所以大多數(shù)情況下,我們建議用copy东帅,以免因可變字符串的修改導(dǎo)致的一些非預(yù)期問(wèn)題压固。