我記得剛開(kāi)始開(kāi)發(fā)的時(shí)候藐窄,有一段時(shí)間我一直以為淺拷貝==copy资昧, mutableCopy==深拷貝, 由于沒(méi)有仔細(xì)研究荆忍,鬧過(guò)一段時(shí)間笑話格带。
深拷貝淺拷貝的概念直接抄錄如下:
淺拷貝:指針拷貝,不產(chǎn)生新的對(duì)象刹枉,源對(duì)象的引用計(jì)數(shù)器+1叽唱;
深拷貝:對(duì)象拷貝,會(huì)產(chǎn)生新的對(duì)象微宝,源對(duì)象的引用計(jì)數(shù)器不變棺亭;
Example 1
NSArray * array = [NSArray arrayWithObjects:@"abc", @"lucy", nil];
NSMutableArray * array1 = [array copy];
// 調(diào)用這個(gè)方法會(huì)crash
// [array1 addObject:@"Lili"];
NSMutableArray * array2 = [array mutableCopy];
[array2 addObject:@"Lili"];
NSLog(@"array: %@ -%p",[array class],array);
NSLog(@"array1: %@ -%p",[array1 class],array1);
NSLog(@"array2: %@ -%p",[array2 class],array2);
打印結(jié)果:
不可變類型array的copy操作是淺拷貝,生成一個(gè)不可變對(duì)象蟋软;mutableCopy是深拷貝镶摘,生成一個(gè)可變對(duì)象嗽桩。
Example 2
NSMutableArray * array = [NSMutableArray arrayWithObjects:@"abc", @"lucy", nil];
NSMutableArray * array1 = [array copy];
// 調(diào)用這個(gè)方法會(huì)crash
// [array1 addObject:@"Lili"];
NSMutableArray * array2 = [array mutableCopy];
[array2 addObject:@"Lili"];
NSLog(@"array: %@ -%p",[array class],array);
NSLog(@"array1: %@ -%p",[array1 class],array1);
NSLog(@"array2: %@ -%p",[array2 class],array2);
/ ** 打印結(jié)果
array: __NSArrayM -0x600002be7750
array1: __NSArrayI -0x6000025afe80
array2: __NSArrayM -0x600002be7a20
*/
可變類型array的copy操作是深拷貝,生成一個(gè)不可變對(duì)象凄敢;mutableCopy是深拷貝碌冶,生成一個(gè)可變對(duì)象。
原對(duì)象類型 | 拷貝方法 | 深/淺拷貝 | 副本對(duì)象類型 |
---|---|---|---|
NSArray | copy | 淺拷貝 | NSArray |
NSArray | mutableCopy | 深拷貝 | NSMutableArray |
NSMutableArray | copy | 深拷貝 | NSArray |
NSMutableArray | mutableCopy | 深拷貝 | NSMutableArray |
Example 3 單層深拷貝和完全深拷貝
NSMutableString * str1 = [NSMutableString stringWithString:@"Bian"] ;
NSMutableString * str2 = [NSMutableString stringWithString:@"Sun"] ;
NSMutableArray * mutableArr = [[NSMutableArray alloc] initWithObjects:str1,str2, nil];
NSMutableArray * copyMutableArr = [mutableArr mutableCopy];
NSLog(@"mutableArr:%p %p %p",mutableArr,mutableArr[0],mutableArr[1]);
NSLog(@"copyMutableArr:%p %p %p",copyMutableArr,copyMutableArr[0],copyMutableArr[1]);
// 修改str1的值
[str1 insertString:@"abc" atIndex:0];
NSLog(@"mutableArr:%p %p %p",mutableArr,mutableArr[0],mutableArr[1]);
NSLog(@"copyMutableArr:%p %p %p",copyMutableArr,copyMutableArr[0],copyMutableArr[1]);
NSLog(@"%@",copyMutableArr[0]);
/** 打印結(jié)果:
mutableArr:0x600003ddaa90 0x600003ddaa30 0x600003dda9d0
copyMutableArr:0x600003ddaac0 0x600003ddaa30 0x600003dda9d0
mutableArr:0x600003ddaa90 0x600003ddaa30 0x600003dda9d0
copyMutableArr:0x600003ddaac0 0x600003ddaa30 0x600003dda9d0
copyMutableArr的str1的值:abcBian
*/
mutableArr的深拷貝copyMutableArr開(kāi)辟了新的內(nèi)存贡未,但是里面值得內(nèi)存地址還和mutableArr共享一份地址种樱,明顯就是指針拷貝,所以說(shuō)這不是完全意義上的深拷貝俊卤,叫單層深拷貝嫩挤!
那么如何實(shí)現(xiàn)完全深拷貝呢?
如下
//只需這樣創(chuàng)建深拷貝,就是完全深拷貝
NSMutableArray * copyMutableArr = [[NSMutableArray alloc] initWithArray:mutableArr copyItems:YES];
結(jié)論:
- 可變對(duì)象的copy和mutableCopy方法都是深拷貝消恍;
- 不可變對(duì)象的copy方法是淺拷貝岂昭,mutableCopy方法是深拷貝;
- copy方法返回的對(duì)象都是不可變對(duì)象狠怨。