問: 為什么要用 copy
修飾 NSString
嗦嗡?
帶著問題我們進(jìn)行如下討論: 測試代碼
1蓖租、不可變字符串copy
NSString *str = @"string";
NSLog(@"%p",str);
NSString *strCopy1 = [str copy];
NSLog(@"%p",strCopy1);
NSMutableString *strCopy2 = [str copy];
NSLog(@"%p",strCopy2);
NSString *strCopy3 = [str copy];
NSLog(@"%p",strCopy3);
NSMutableString *strCopy4 = [str copy];
NSLog(@"%p",strCopy4);
//如果取消下面的注釋粱侣,則crash羊壹,strCopy2實質(zhì)還是不可變字符串
// [strCopy2 appendString:@"1"];
控制臺輸出如下
2016-12-22 14:25:11.636 CopyAndStrong[16067:400558] 0x10adab098
2016-12-22 14:25:11.636 CopyAndStrong[16067:400558] 0x10adab098
2016-12-22 14:25:11.637 CopyAndStrong[16067:400558] 0x10adab098
2016-12-22 14:25:11.637 CopyAndStrong[16067:400558] 0x10adab098
2016-12-22 14:25:11.637 CopyAndStrong[16067:400558] 0x10adab098
NSString的copy只是相當(dāng)于“強(qiáng)引用” ,也就是淺拷貝齐婴。
下圖是該字符串的isa指針類型油猫,根據(jù)名稱就可以知道0x10adab098
在常量區(qū),存放字符串量柠偶,而不論你對一個字符串常量怎么copy情妖,他依然還是靜靜地在常量區(qū)做一個字符串常量
Snip20161222_5.png
2、不可變字符串mutableCopy
NSString *str = @"string";
NSLog(@"%p",str);
NSString *strMutableCopy1 = [str mutableCopy];
NSLog(@"%p",strMutableCopy1);
NSMutableString *strMutableCopy2 = [str mutableCopy];
NSLog(@"%p",strMutableCopy2);
NSString *strMutableCopy3 = [str mutableCopy];
NSLog(@"%p",strMutableCopy3);
NSMutableString *strMutableCopy4 = [str mutableCopy];
NSLog(@"%p",strMutableCopy4);
控制臺輸出如下
2016-12-22 14:36:20.605 CopyAndStrong[16067:400558] 0x10adab098
2016-12-22 14:36:20.605 CopyAndStrong[16067:400558] 0x60800007db80
2016-12-22 14:36:20.605 CopyAndStrong[16067:400558] 0x600000261e40
2016-12-22 14:36:20.606 CopyAndStrong[16067:400558] 0x608000260300
2016-12-22 14:36:20.606 CopyAndStrong[16067:400558] 0x60800007db40
每一個mutableCopy的字符串诱担,地址都不同毡证,而且他們的樣式和 0x10adab098
明顯不同,這里我執(zhí)行如下代碼
UIView *view = [UIView new];
NSLog(@"%p",view); // 輸出 `0x7fc4ec503e50`
發(fā)現(xiàn)堆區(qū)對象的地址和mutableCopy
的字符串得到的字符串地址極為相似蔫仙,得出結(jié)論mutableCopy之后的字符串在堆區(qū)料睛,而他們的類型其實都是NSMutableString
,參考如下截圖
Snip20161222_6.png
3摇邦、可變字符串的copy
NSString *str = @"string";
NSLog(@"%p",str);
NSMutableString *mutableStr = [str mutableCopy];
NSLog(@"%p",mutableStr);
NSString *MutableStrCopy1 = [mutableStr copy];
NSLog(@"%p",MutableStrCopy1);
NSMutableString *MutableStrCopy2 = [mutableStr copy];
NSLog(@"%p",MutableStrCopy2);
NSString *MutableStrCopy3 = [mutableStr copy];
NSLog(@"%p",MutableStrCopy3);
NSMutableString *MutableStrCopy4 = [mutableStr copy];
NSLog(@"%p",MutableStrCopy4);
// [MutableStrCopy2 appendString:@"1"];//取消注釋就會crash秦效,copy之后實際是不可變字符串
控制臺輸出如下
2016-12-22 14:54:26.257 CopyAndStrong[16151:410074] 0x106181098
2016-12-22 14:54:26.257 CopyAndStrong[16151:410074] 0x608000078240
2016-12-22 14:54:26.258 CopyAndStrong[16151:410074] 0xa00676e697274736
2016-12-22 14:54:26.258 CopyAndStrong[16151:410074] 0xa00676e697274736
2016-12-22 14:54:26.258 CopyAndStrong[16151:410074] 0xa00676e697274736
2016-12-22 14:54:26.258 CopyAndStrong[16151:410074] 0xa00676e697274736
四次copy,結(jié)果都是同一個地址涎嚼,而且這里打印出來的地址有點奇怪阱州,我在控制臺看到如下描述:
Snip20161222_8.png
查了資料發(fā)現(xiàn)一個叫做
Tagged Pointer
的東西,這里不做解釋法梯。苔货。。
4立哑、可變字符串的mutableCopy
NSString *str = @"string";
NSLog(@"%p",str);
NSMutableString *mutableStr = [str mutableCopy];
NSLog(@"%p",mutableStr);
NSString *MutableStrMutableCopy1 = [mutableStr mutableCopy];
NSLog(@"%p",MutableStrMutableCopy1);
NSMutableString *MutableStrMutableCopy2 = [mutableStr mutableCopy];
NSLog(@"%p",MutableStrMutableCopy2);
NSString *MutableStrMutableCopy3 = [mutableStr mutableCopy];
NSLog(@"%p",MutableStrMutableCopy3);
NSMutableString *MutableStrMutableCopy4 = [mutableStr mutableCopy];
NSLog(@"%p",MutableStrMutableCopy4);
控制臺輸出如下
2016-12-22 15:13:45.732 CopyAndStrong[16356:430316] 0x10e0fa098
2016-12-22 15:13:45.732 CopyAndStrong[16356:430316] 0x60000006e240
2016-12-22 15:13:45.733 CopyAndStrong[16356:430316] 0x600000071ac0
2016-12-22 15:13:45.733 CopyAndStrong[16356:430316] 0x618000072740
2016-12-22 15:13:45.733 CopyAndStrong[16356:430316] 0x610000071dc0
2016-12-22 15:13:45.733 CopyAndStrong[16356:430316] 0x608000070dc0
類似不可變字符串的mutableCopy
總結(jié):
- copy產(chǎn)生不可變字符串夜惭,mutableCopy產(chǎn)生可變字符串;
- 只要mutablecopy就會開辟空間, copy可變字符串才會開辟空間铛绰;
答: 為什么要用 copy
修飾 NSString
诈茧?
如果用 NSString
強(qiáng)引用一個 NSMutableString
,他們實際都是指向同一個NSMutableString
, 而一旦NSMutableString
的值改變,那么所謂的NSString
也隨之改變