前言:
提到iOS中的浅复制和深复制的区别,大家都知道浅复制过来的是对象的地址,而深复制,相当于重新开辟了内存空间,存储这个对象。
用代码说话
①单个对象的浅复制与深复制
/// 单个对象 浅复制、深赋值
- (void)ordinaryCopyVSMutableCopy {
NSString *str = @"hehe";
NSLog(@"源字符:%p",str);
//浅
NSString *cStr = [str copy];
NSLog(@"浅复制: Cstr = %p",cStr);
NSString *temp = [str copyWithZone:nil];
NSLog(@"copyWithZone: temp = %p",temp);
//深
NSString *mStr = [str mutableCopy];
NSLog(@"深复制: mStr = %p",mStr);
}
输出结果:
tips:可以看到
copy
、copyWithZone
方法都是浅复制,对象的地址并没有改变,而mutableCopy
重新开辟了内存控件,是深复制
数组及集合类对象的浅复制、深复制、完全复制
我们先定义一个原始数组
NSArray *originArr = [NSArray arrayWithObjects:@"1",@"2", nil];
NSLog(@"原数组 地址:%p",originArr);
NSLog(@"原数组中对象的地址: %p,%p \n",originArr[0],originArr[1]);
看代码:
①对数组进行浅复制
//对数组进行浅复制
NSArray *copyArr = [originArr copy];
NSLog(@"浅复制 地址:%p",copyArr);
NSLog(@"浅复制数组中对象的地址: %p,%p \n",copyArr[0],copyArr[1]);
对比输出结果看:
tips:可以看到 不论是数组本身还是数组中的元素,地址都没有发生变化,这就是完完全全的浅复制
那么问题1:
[NSArray arrayWithArray:originArr]
是浅复制 还是 深复制呢
NSArray *arr = [NSArray arrayWithArray:originArr];
NSLog(@"arrayWithArray深复制 地址:%p",arr);
NSLog(@"arrayWithArray深复制数组中对象的地址: %p,%p \n",arr[0],arr[1]);
结果:
tips:
arr
相比于源数组,算是一次深复制,但是数组中的元素地址依旧没有发生变化
②对数组进行深复制
NSArray *mCopyArr = [originArr mutableCopy];
NSLog(@"深复制 地址:%p",mCopyArr);
NSLog(@"深复制数组中对象的地址: %p,%p \n",mCopyArr[0],mCopyArr[1]);
打印地址发现:
可以发现
mCopyArr
相比于原先的数组算是深复制了,但是内部的元素依旧是原先数组中的元素
问题2:[[NSArray alloc] initWithArray:.... copyItems:true]
是浅复制 还是 深复制呢
NSArray *array = [[NSArray alloc] initWithObjects:[[NSMutableString alloc] initWithString:@"1"], @"2",nil];
NSLog(@"array 地址: %p",array);
NSLog(@"array中元素的地址 :%p,%p",array[0],array[1]);
NSArray *arrWithCopyItem = [[NSArray alloc] initWithArray:array copyItems:true];
NSLog(@"arrWithCopyItem深复制 地址:%p",arrWithCopyItem);
NSLog(@"arrWithCopyItem深复制数组中对象的地址: %p,%p \n",arrWithCopyItem[0],arrWithCopyItem[1]);
输出结果:
可以看到,
arrWithCopyItem
对于源数组array
中的可变对象进行的是深复制,对不可变对象做的是浅复制,所以可以称,[[NSArray alloc] initWithArray:.... copyItems:true]
方法是与源数组做了一次不完全的深复制,对于其中的不可变对象依旧是浅复制tips:字典的
[NSDictionary alloc] initWithDictionary:... copyItems:..
这个方法结果同上
问题来了:这不算真正意义上的深复制,即完全复制,那用什么方法可以实现完全复制呢?
②对数组进行完全复制
方法有很多种,这里简单介绍两种:
一:归档、解挡操作
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:originArr];
NSData *aData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSArray *mmCopyArr = (NSArray *)aData;
NSLog(@"①归档深复制 地址:%p",mmCopyArr);
NSLog(@"①归档深复制数组中对象的地址: %p,%p \n",mmCopyArr[0],mmCopyArr[1]);
可以看到,不仅数组本身为深复制,数组中的元素也都重新开辟了内存空间
二:对数组进行遍历深复制,该方法较为简单,就不写代码了