copy就是複製獲得一個不可變的對象,mutableCopy就是複製獲得一個可變的對象。按照不一樣狀況,如下分別舉例說明:spa
1. 對非容器類對象的拷貝(好比 NSString,NSMutableString)對象
(1)被拷貝對象自己不可變(如NSString),代碼展現請往下看: 內存
從如下代碼輸出內容能夠看出:字符串
1.將A直接賦值給B時=>A和B擁有相同的內存地址,其值固然也相同;但A(或B)被從新賦值後,A(或B)擁有了新的內存地址,值也相應改變,然而這樣的改變不會影響另外一方B(或A),另外一方仍然具備跟以前同樣的地址和值。原型
2.將A copy到B時=>A和B擁有相同的內存地址,且當A被從新賦值後,A擁有了新的內存地址,其值也相應改變,但這樣的改變不會影響B,B仍然具備跟以前同樣的地址和值。string
3.將A mutableCopy到B時=>B的地址和A的不相同,B的值能夠被從新設定(是setString,而不是指賦值);且A被從新賦值也不會影響B,一樣B的改變也不會影響A。it
代碼從這裏開始++++++++++++++++++++++++++++++++++++++++++++++++++table
NSLog(@"##############以不可變字符串爲原型##########");容器
NSString *strFirst = @"abc";變量
NSLog(@"1.strFirst address : %p; %@",strFirst, strFirst);
NSString *strSecond = strFirst;
NSLog(@"2.strSecond address : %p; %@",strSecond, strSecond);
NSString *strFirstCopy = [strFirst copy];//至關於strFirst所指向的地址引用計數+1(地址同樣)
NSLog(@"3.strFirstCopy address : %p; %@",strFirstCopy, strFirstCopy);
NSString *strFirstMutableCopy = [strFirst mutableCopy];
NSLog(@"4.strFirstMutableCopy address : %p; %@",strFirstMutableCopy, strFirstMutableCopy);
strFirst = @"bcd";//賦值至關於從新分配地址
NSLog(@"5.strFirst address : %p; %@",strFirst, strFirst);
NSLog(@"5.strSecond address : %p; %@",strSecond, strSecond);//
NSLog(@"5.strFirstCopy address : %p; %@",strFirstCopy, strFirstCopy);
NSLog(@"5.strFirstMutableCopy address : %p; %@",strFirstMutableCopy, strFirstMutableCopy);
對於以上示例代碼的控制檯輸出以下:
2016-04-28 13:46:33.504 copyTest[4299:93432] ##############以不可變字符串爲原型##########
2016-04-28 13:46:33.504 copyTest[4299:93432] 1.strFirst address : 0x10244b0e8; abc
2016-04-28 13:46:33.504 copyTest[4299:93432] 2.strSecond address : 0x10244b0e8; abc
2016-04-28 13:46:33.505 copyTest[4299:93432] 3.strFirstCopy address : 0x10244b0e8; abc
2016-04-28 13:46:33.505 copyTest[4299:93432] 4.strFirstMutableCopy address : 0x7f9882c1d410; abc
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strFirst address : 0x10244b188; bcd
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strSecond address : 0x10244b0e8; abc
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strFirstCopy address : 0x10244b0e8; abc
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strFirstMutableCopy address : 0x7f9882c1d410; abc
(2)被拷貝對象自己可變(如NSMutableString),代碼展現請往下看:
從如下代碼輸出內容能夠看出:
1.將A直接賦值給B時=>A和B擁有相同的內存地址,其值固然也相同;當A(或B)被從新設定(是setString,而不是指賦值),另外一方值也會跟着改變;但A(或B)被從新賦值後,A(或B)擁有了新的內存地址,值也相應改變,然而這樣的改變不會影響另外一方B(或A),另外一方仍然具備跟以前同樣的地址和值。
2.將A copy到B時=>B跟A的地址不一樣,且B不能被從新設定值(setString),A的改變不會影響B,B的改變也不影響A。
3.將A mutableCopy到B時=>B的地址和A的不相同,B的值也能夠被從新設定(是setString,而不是指賦值);且A被從新賦值也不會影響B,一樣B的改變也不會影響A。
代碼從這裏開始++++++++++++++++++++++++++++++++++++++++++++++++++
NSLog(@"##############以可變字符串爲原型###########");
NSMutableString *strVFirst = [NSMutableString stringWithString:@"a"];
NSLog(@"1.strVFirst address : %p; %@",strVFirst, strVFirst);
NSMutableString *strVSecond = strVFirst;
NSLog(@"2.strVSecond address : %p; %@",strVSecond, strVSecond);
NSMutableString *strVFirstCopy = [strVFirst copy];
NSLog(@"3.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);
NSMutableString *strVFirstMutableCopy = [strVFirst mutableCopy];
NSLog(@"4.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);
[strVFirst setString:@"b"];
NSLog(@"5.strVFirst address : %p; %@",strVFirst, strVFirst);
NSLog(@"5.strVSecond address : %p; %@",strVSecond, strVSecond);
NSLog(@"5.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);
NSLog(@"5.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);
[strVSecond setString:@"c"];
NSLog(@"6.strVFirst address : %p; %@",strVFirst, strVFirst);
NSLog(@"6.strVSecond address : %p; %@",strVSecond, strVSecond);
NSLog(@"6.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);
NSLog(@"6.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);
[strVFirstMutableCopy setString:@"c"];
NSLog(@"7.strVFirst address : %p; %@",strVFirst, strVFirst);
NSLog(@"7.strVSecond address : %p; %@",strVSecond, strVSecond);
NSLog(@"7.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);
NSLog(@"7.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);
對於以上示例代碼的控制檯輸出以下:
2016-04-28 13:46:33.505 copyTest[4299:93432] ##############以可變字符串爲原型###########
2016-04-28 13:46:33.505 copyTest[4299:93432] 1.strVFirst address : 0x7f9882f99080; a
2016-04-28 13:46:33.505 copyTest[4299:93432] 2.strVSecond address : 0x7f9882f99080; a
2016-04-28 13:46:33.505 copyTest[4299:93432] 3.strVFirstCopy address : 0xa000000000000611; a
2016-04-28 13:46:33.505 copyTest[4299:93432] 4.strVFirstMutableCopy address : 0x7f9882f990c0; a
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVFirst address : 0x7f9882f99080; b
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVSecond address : 0x7f9882f99080; b
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVFirstCopy address : 0xa000000000000611; a
2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVFirstMutableCopy address : 0x7f9882f990c0; a
2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVFirst address : 0x7f9882f99080; c
2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVSecond address : 0x7f9882f99080; c
2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVFirstCopy address : 0xa000000000000611; a
2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVFirstMutableCopy address : 0x7f9882f990c0; a
2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVFirst address : 0x7f9882f99080; c
2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVSecond address : 0x7f9882f99080; c
2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVFirstCopy address : 0xa000000000000611; a
2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVFirstMutableCopy address : 0x7f9882f990c0; c
對於非容器類變量的拷貝能夠作個總結:對不可變對象使用copy,至關於引用計數加1,不會分配新的內存;對不可變對象使用mutableCopy,會分配新的內存地址,新舊對象的改變不會互相影響;對可變對象使用copy或mutableCopy,都會分配新的內存,新舊對象的改變不相互影響。