其實(shí)也不算深度解析啦凹炸,主要是題目要響亮一點(diǎn)大家才有看的欲望嘛!V绲堋啤它!
首先關(guān)于Copy想必在面試題中大家見(jiàn)過(guò)很多,下面我就寫(xiě)一下我對(duì)Copy的理解。
1.Copy是什么变骡?离赫??
copy和mutableCopy是方法塌碌,是NSObject內(nèi)定義的方法渊胸。
2.Copy有什么用?台妆?翎猛?
copy顧名思義就是拷貝或者說(shuō)克隆,所以copy的目的就是復(fù)制一份原來(lái)的內(nèi)容接剩,進(jìn)一步思考為什么需要拷貝切厘?顯然:拷貝的目的就是改變?cè)瓉?lái)的內(nèi)容不影響副本,改變副本也不影響原來(lái)的內(nèi)容懊缺。
3.從NSString,NSMutableString,NSArray,NSMutableArray說(shuō)明深拷貝和淺拷貝的區(qū)別
首先大家來(lái)想一下為什么要用到Copy疫稿??Copy的目的所在是什么鹃两?為什么需要生成一個(gè)新的對(duì)象呢遗座??俊扳?
Copy是為了互不干擾途蒋,生成兩個(gè)對(duì)象是為了相互改變的時(shí)候不影響另外一個(gè)對(duì)象。
其次大家要牢記一點(diǎn)馋记,使用Copy方法得到的是不可變對(duì)象碎绎,使用mutableCopy方法得到的必須是可變對(duì)象。
一.NSString抗果、NSMutableString非容器對(duì)象分析
1.不可變字符串的copy和mutableCopy
NSString *str = @"xiaoming";
NSString *str1 = [str copy];
NSMutableString * str2 = [str mutableCopy];
NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",str,str,NSStringFromClass([str class]),str1,str1,NSStringFromClass([str1 class]),str2,str2,NSStringFromClass([str2 class]));
打印結(jié)果如下:
----str:0x10c8e4068,xiaoming,__NSCFConstantString----str1:0x10c8e4068,xiaoming,__NSCFConstantString----str2:0x608000266ac0,xiaoming,__NSCFString
通過(guò)上面的打印結(jié)果大家可以看到不可變的字符串經(jīng)過(guò)copy之后沒(méi)有生成對(duì)象筋帖,得到的是不可變字符串,經(jīng)過(guò)mutableCopy之后生成了新的對(duì)象冤馏,得到是可變字符串日麸。
為什么copy沒(méi)有得到對(duì)象呢?逮光?代箭?因?yàn)樵瓉?lái)的對(duì)象是不可以修改的,新拷貝的對(duì)象也是不可修改的涕刚,所以不會(huì)影響到另外一個(gè)對(duì)象嗡综。已經(jīng)符合拷貝的目的 了,所以杜漠,OC為了對(duì)內(nèi)存進(jìn)行優(yōu)化, 就不會(huì)生成一個(gè)新的對(duì)象极景。
為什么mutableCopy會(huì)生成新的對(duì)象呢察净?生成的是一個(gè)可變對(duì)象,這樣兩個(gè)對(duì)象其中一個(gè)對(duì)象改變而不影響另外一個(gè)對(duì)象盼樟。
2.可變字符串的copy和mutableCopy
NSMutableString *mulStr = [NSMutableString stringWithFormat:@"abc"];
NSString *mulStr1 = [mulStr copy];
NSMutableString * mulStr2 = [mulStr mutableCopy];
NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",mulStr,mulStr,NSStringFromClass([mulStr class]),mulStr1,mulStr1,NSStringFromClass([mulStr1 class]),mulStr2,mulStr2,NSStringFromClass([mulStr2 class]));
打印結(jié)果如下:
----str:0x600000260180,abc,__NSCFString----str1:0xa000000006362613,abc,NSTaggedPointerString----str2:0x6000002601c0,abc,__NSCFString
通過(guò)上面的打印結(jié)果可以看出來(lái)可變字符串經(jīng)過(guò)copy和mutableCopy之后都創(chuàng)建了新的對(duì)象氢卡。經(jīng)過(guò)copy之后得到的是不可變字符串,經(jīng)過(guò)mutableCopy之后 得到的是可變字符串晨缴。
為什么都會(huì)生成對(duì)象呢译秦??击碗?因?yàn)榭勺冏址緛?lái)就是可以改變的筑悴,為了改變互不干擾,從而生成新的對(duì)象稍途,符合拷貝的目的雷猪。
二:NSArray、NSMutableArray容器對(duì)象分析
首先容器對(duì)象和非容器對(duì)象一樣同樣遵從下面的總結(jié):
如果對(duì)一不可變對(duì)象復(fù)制晰房,copy是指針復(fù)制(淺拷貝)、mutableCopy就是對(duì)象復(fù)制(深拷貝)射沟。
如果是對(duì)可變對(duì)象復(fù)制殊者,都是深拷貝,但是copy返回的對(duì)象是不可變的验夯。
1.NSArray的copy和mutableCopy?
NSArray *array = [[NSArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"a"],@"b",@"c", nil];
NSArray *array1 = [array copy];
NSMutableArray *array2 = [array mutableCopy];
// NSArray *array3 = [array mutableCopy];
NSArray *array3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];
NSLog(@"----array:%p,----array1:%p,-----array2:%p,----array3:%p",array,array1,array2,array3);
NSMutableString *str1 = [array objectAtIndex:0];
[str1 appendString:@"hahhaha"];
[array2 insertObject:@"111111" atIndex:0];
NSMutableString *str2 = [array2 objectAtIndex:1];
[str2 appendString:@"111111"];
NSLog(@"----array:%@,----array1:%@,-----array2:%@,----array3:%@",array,array1,array2,array3);
打印結(jié)果如下:
?----array:0x608000242070,----array1:0x608000242070,-----array2:0x608000242b50,----array3:0x608000242d90
?----array:(
ahahhaha111111,
b,
c
),----array1:(
ahahhaha111111,
b,
c
),-----array2:(
111111,
ahahhaha111111,
b,
c
),----array3:(
a,
b,
c
)
通過(guò)上面的打印可以看出來(lái)NSArray 經(jīng)過(guò)Copy之后沒(méi)有創(chuàng)建對(duì)象猖吴,經(jīng)過(guò)mutableCopy之后創(chuàng)建了新的對(duì)象,具體原因和NSString一樣挥转,但是里面的元素對(duì)象還是指針拷貝海蔽,要想做到對(duì)象拷貝,可以使用歸檔的方法绑谣。
2.NSMutableArray 的copy和MutableCopy
NSMutableArray *mulArray = [[NSMutableArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"abc"],@"def", nil];
NSMutableArray *mulArray1 = [mulArray copy];
NSMutableArray *mulArray2 = [mulArray mutableCopy];
NSLog(@"----array:%p,----arrar1:%p,----array2:%p",mulArray,mulArray1,mulArray2);
NSMutableString *mulstr = [mulArray objectAtIndex:0];
[mulstr appendString:@"abc"];
NSLog(@"----array:%@,-----array1:%@,-----array2:%@",mulArray,mulArray1,mulArray2);
NSLog(@"----array:%@,-----array1:%@,-----array2:%@",NSStringFromClass([mulArray class]) ,NSStringFromClass([mulArray1 class]),NSStringFromClass([mulArray2 class]));
打印結(jié)果如下:
----array:0x60000005af40,----arrar1:0x60000002b1a0,----array2:0x60000005ad60
----array:(
abcabc,
def
),-----array1:(
abcabc,
def
),-----array2:(
abcabc,
def
)
通過(guò)上面的打印可以看出來(lái)NSArray 經(jīng)過(guò)Copy和mutableCopy之后都創(chuàng)建新的對(duì)象党窜,具體原因和NSString一樣,但是里面的元素對(duì)象還是指針拷貝借宵,要想做到對(duì)象拷貝幌衣,可以使用歸檔的方法。
但是大家還要牢記一點(diǎn):NSMutableArray多次copy每次都會(huì)新建對(duì)象而NSArray多次copy只新建一次對(duì)象壤玫。
4.總結(jié)
正是因?yàn)檎{(diào)用copy方法有時(shí)候會(huì)生成一個(gè)新的對(duì)象, 有時(shí)候不會(huì)生成一個(gè)新的對(duì)象所以:
如果沒(méi)有生成新的對(duì)象, 我們稱之為淺拷貝, 本質(zhì)就是指針拷貝
如果生成了新的對(duì)象, 我們稱之為深拷貝, 本質(zhì)就是會(huì)創(chuàng)建一個(gè)新的對(duì)象
最后:最重要的還是記住拷貝的目的豁护,這樣理解深淺拷貝都會(huì)變得非常簡(jiǎn)單,改變?cè)瓉?lái)的內(nèi)容不影響副本欲间,改變副本也不影響原來(lái)的內(nèi)容