copy、mutableCopy、單層深拷貝

我記得剛開始開發(fā)的時(shí)候,有一段時(shí)間我一直以為淺拷貝==copy, mutableCopy==深拷貝, 由于沒有仔細(xì)研究,鬧過一段時(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é)果:


example-1.png

不可變類型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開辟了新的內(nèi)存,但是里面值得內(nèi)存地址還和mutableArr共享一份地址,明顯就是指針拷貝,所以說這不是完全意義上的深拷貝,叫單層深拷貝!

那么如何實(shí)現(xiàn)完全深拷貝呢?
如下
//只需這樣創(chuàng)建深拷貝,就是完全深拷貝
 NSMutableArray * copyMutableArr = [[NSMutableArray alloc] initWithArray:mutableArr copyItems:YES];

結(jié)論:

  • 可變對(duì)象的copy和mutableCopy方法都是深拷貝;
  • 不可變對(duì)象的copy方法是淺拷貝,mutableCopy方法是深拷貝;
  • copy方法返回的對(duì)象都是不可變對(duì)象。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容