淺復(fù)制——即指針復(fù)制醇锚,不創(chuàng)建新的對(duì)象芦劣;
深復(fù)制——即內(nèi)容復(fù)制,創(chuàng)建一個(gè)新的對(duì)象丁寄。
(這么精辟的話當(dāng)然出自高手之口)
引自:http://www.reibang.com/p/ebbac2fec4c6
1 NSString和NSMutableString
(1) NSString發(fā)送copy消息時(shí)會(huì)進(jìn)行淺復(fù)制:
NSString *name = @"name";
NSString *nameFromCopy = [name copy];
NSLog(@"%p", name);
NSLog(@"%p", nameFromCopy);
[2283:101871] 0x1000020b0
[2283:101871] 0x1000020b0
看上去對(duì)NSString的copy好像什么都沒做柑营,實(shí)際上是有的屈雄,ARC會(huì)在后臺(tái)調(diào)用retain給這個(gè)字符串添加一個(gè)引用計(jì)數(shù)。
(2)NSString發(fā)送mutableCopy消息是深復(fù)制:
NSString *name = @"name";
NSString *nameFromCopy = [name mutableCopy];
NSLog(@"%p", name);
NSLog(@"%p", nameFromCopy);
[2743:131031] 0x1000020b0
[2743:131031] 0x100700200
(3) 向NSMutableString發(fā)送copy消息會(huì)進(jìn)行深復(fù)制:
NSMutableString *name = [[NSMutableString alloc] initWithString:@"name"];
NSString *nameFromCopy = [name copy];
NSLog(@"%p", name);
NSLog(@"%p", nameFromCopy);
[2270:97375] 0x100100540
[2270:97375] 0x656d616e45
(4) NSMutableString的mutableCopy消息是深復(fù)制:
NSMutableString *name = [[NSMutableString alloc] initWithString:@"name"];
NSString *nameFromCopy = [name mutableCopy];
NSLog(@"%p", name);
NSLog(@"%p", nameFromCopy);
[2753:133279] 0x1005034d0
[2753:133279] 0x100503650
小結(jié):
2 NSArray和NSMutableArray
(1) NSArray的copy是淺復(fù)制
NSArray *array = [[NSArray alloc] init];
NSArray *arrayFromCopy = [array copy];
NSLog(@"%p", array);
NSLog(@"%p", arrayFromCopy);
[2798:141184] 0x100501360
[2798:141184] 0x100501360
(2)NSMutable的copy是深復(fù)制
NSMutableArray *array = [[NSMutableArray alloc] init];
NSArray *arrayFromCopy = [array copy];
NSLog(@"%p", array);
NSLog(@"%p", arrayFromCopy);
[2871:152574] 0x100700420
[2871:152574] 0x100501360
(3)NSArray的mutableCopy是深復(fù)制
NSArray *array = [[NSArray alloc] init];
NSArray *arrayFromCopy = [array mutableCopy];
NSLog(@"%p", array);
NSLog(@"%p", arrayFromCopy);
[2881:155075] 0x100201360
[2881:155075] 0x100700a90
(4)NSMutableArray的mutableCopy是深復(fù)制
NSMutableArray *array = [[NSMutableArray alloc] init];
NSArray *arrayFromCopy = [array mutableCopy];
NSLog(@"%p", array);
NSLog(@"%p", arrayFromCopy);
[2891:156290] 0x1007001e0
[2891:156290] 0x100700380
也就是說官套,得出了跟NSString和NSMutableString之間一樣的結(jié)論酒奶??
表面上來看奶赔,確實(shí)是這樣惋嚎。但是,數(shù)組作為一個(gè)容器站刑,肯定還要考慮里面的數(shù)據(jù)情況另伍。我們嘗試在數(shù)組里放點(diǎn)實(shí)驗(yàn)數(shù)據(jù),比如幾個(gè)字符串:
NSArray的copy:
//創(chuàng)建3個(gè)可變字符串
NSMutableString *string1 = [NSMutableString stringWithFormat:@"a"];
NSMutableString *string2 = [NSMutableString stringWithFormat:@"b"];
NSMutableString *string3 = [NSMutableString stringWithFormat:@"c"];
//將3個(gè)字符串放入數(shù)組中
NSArray *array = [NSArray arrayWithObjects:string1, string2, string3, nil];
NSArray *arrayFromCopy = [array copy];
NSLog(@"%p", array); //輸出原數(shù)組及其元素的地址
NSLog(@"%p", array[0]);
NSLog(@"%p", array[1]);
NSLog(@"%p", array[2]);
printf("\n");
NSLog(@"%p", arrayFromCopy); //輸出copy的數(shù)組及其元素的地址
NSLog(@"%p", arrayFromCopy[0]);
NSLog(@"%p", arrayFromCopy[1]);
NSLog(@"%p", arrayFromCopy[2]);
[3141:182137] 0x100701030
[3141:182137] 0x100700200
[3141:182137] 0x1007003e0
[3141:182137] 0x100700440
[3141:182137] 0x100701030
[3141:182137] 0x100700200
[3141:182137] 0x1007003e0
[3141:182137] 0x100700440
NSArray的mutableCopy
NSArray *array = [NSArray arrayWithObjects:string1, string2, string3, nil];
NSArray *arrayFromCopy = [array mutableCopy];
NSLog(@"%p", array); //輸出原數(shù)組及其元素的地址
NSLog(@"%p", array[0]);
NSLog(@"%p", array[1]);
NSLog(@"%p", array[2]);
printf("\n");
NSLog(@"%p", arrayFromCopy); //輸出copy的數(shù)組及其元素的地址
NSLog(@"%p", arrayFromCopy[0]);
NSLog(@"%p", arrayFromCopy[1]);
NSLog(@"%p", arrayFromCopy[2]);
[3151:184027] 0x100103410
[3151:184027] 0x1001024d0
[3151:184027] 0x100102390
[3151:184027] 0x1001023d0
[3151:184027] 0x100102bf0
[3151:184027] 0x1001024d0
[3151:184027] 0x100102390
[3151:184027] 0x1001023d0
所以绞旅,其實(shí)NSArray的mutableCopy只是對(duì)數(shù)組對(duì)象進(jìn)行了深復(fù)制摆尝,而數(shù)組內(nèi)元素依然是淺復(fù)制。像下圖這樣:
事實(shí)上NSMutableArray的copy和mutableCopy也是這樣因悲,為了節(jié)省篇幅我就不放代碼了堕汞,有興趣的朋友可以自己試一下。
如果想實(shí)現(xiàn)數(shù)組內(nèi)元素也進(jìn)行深復(fù)制晃琳,有個(gè)比較簡(jiǎn)單的方法讯检,就是用NSArray提供的一個(gè)初始化方法
-(instancetype)initWithArray:copyItems:
NSArray *array = [NSArray arrayWithObjects:string1, string2, string3, nil];
NSArray *arrayFromCopy = [[NSArray alloc] initWithArray:array copyItems:YES];
NSLog(@"%p", array); //輸出原數(shù)組及其元素的地址
NSLog(@"%p", array[0]);
NSLog(@"%p", array[1]);
NSLog(@"%p", array[2]);
printf("\n");
NSLog(@"%p", arrayFromCopy); //輸出copy的數(shù)組及其元素的地址
NSLog(@"%p", arrayFromCopy[0]);
NSLog(@"%p", arrayFromCopy[1]);
NSLog(@"%p", arrayFromCopy[2]);
[3166:189328] 0x100106fc0
[3166:189328] 0x100100270
[3166:189328] 0x100105eb0
[3166:189328] 0x100105f10
[3166:189328] 0x100106d90
[3166:189328] 0x6115
[3166:189328] 0x6215
[3166:189328] 0x6315
現(xiàn)在引用情況像這樣:
我猜你現(xiàn)在肯定很想知道琐鲁,下面這種情況的話,用上面的深復(fù)制方法能否奏效:(模仿歪果仁的口吻人灼,聽起來就像是一個(gè)很牛逼的人在說話一樣)
//創(chuàng)建3個(gè)可變字符串
NSMutableString *string1 = [NSMutableString stringWithFormat:@"a"];
NSMutableString *string2 = [NSMutableString stringWithFormat:@"b"];
NSMutableString *string3 = [NSMutableString stringWithFormat:@"c"];
//將string1放入數(shù)組array_0中
NSArray *array_0 = [[NSArray alloc] initWithObjects:string1, nil];
//將array_0围段,string2,string3放入數(shù)組array中
NSArray *array = [NSArray arrayWithObjects:array_0, string2, string3, nil];
//復(fù)制?數(shù)組
NSArray *arrayFromCopy = [[NSArray alloc] initWithArray:array copyItems:YES];
//輸出
NSLog(@"%p", array); //輸出原數(shù)組及其元素的地址
NSLog(@"%p", array[0]);
NSLog(@"%p", array[1]);
NSLog(@"%p", array[2]);
printf("\n");
NSLog(@"%p", arrayFromCopy); //輸出copy的數(shù)組及其元素的地址
NSLog(@"%p", arrayFromCopy[0]);
NSLog(@"%p", arrayFromCopy[1]);
NSLog(@"%p", arrayFromCopy[2]);
printf("\n");
NSLog(@"%p", array[0][0]); //輸出原數(shù)組和copy數(shù)組的數(shù)組的字符串string1地址
NSLog(@"%p", arrayFromCopy[0][0]);
[3203:205170] 0x100106ef0
[3203:205170] 0x1001069b0
[3203:205170] 0x100100200
[3203:205170] 0x100100260
[3203:205170] 0x100106f20
[3203:205170] 0x1001069b0
[3203:205170] 0x6215
[3203:205170] 0x6315
[3203:205170] 0x1001062f0
[3203:205170] 0x1001062f0
這就是答案:
可見NSArray的實(shí)例方法-(instancetype)initWithArray:copyItems:的深復(fù)制到三維數(shù)組已經(jīng)力不從心了投放,如果想對(duì)三維或以上的數(shù)組進(jìn)行徹底深復(fù)制奈泪,就必須使用殺手锏——?dú)w檔。
關(guān)于歸檔跪呈,筆者另文:http://www.reibang.com/p/a0b994d34c0a
這2篇文章循環(huán)引用了:)