面试官:
1.浅拷贝和深拷贝你了解吗?详细说说?
2.修改原对象的值,副本对象会变吗?
3.copy 一个可变的数组,会出现什么结果?
4.用 copy 修饰 NSMutableArray @property (nonatomic, copy) NSMutableArray *myArray;,对myArray 赋值会有什么结果?
5.对属性strong对象进行copy操作,会开辟新内存空间吗?
面试者:浅拷贝是值的拷贝,深拷贝是地址和值的拷贝,巴拉巴拉。。。。。。
copy 和 mutableCopy 你真的理解吗?最近发现很多面试者都不能很好地回答这个问题。所以整理一下相关知识
问题1 浅拷贝和深拷贝理解
1.copy :不拷贝对象本身,只拷贝指向对象的指针
2.mutableCopy: 直接拷贝整个对象内存到另一块内存中
NSArray *array = [NSArray arrayWithObjects:@(2),@(3),@(5),@(8),@(3),@(2),@(5),nil];
NSArray *copyArray = array.copy;
NSArray *mutableArray = array.mutableCopy;
NSLog(@"array===========%p\ncopyArray=============%p\nmutableArray===============%p=",array,copyArray,mutableArray);
输出结果为:
array===========0x60000179bb60
copyArray=============0x60000179bb60
mutableArray===============0x600003ad81b0=
copyArray 与array的指针地址相同,值相同 ,而mutableArray 与array 指针内存地址不同
非常形象的比喻:copy:你和你的影子 mutableCopy 你和你的双胞胎兄弟
问题2 修改原对象的值,副本对象会变吗?先看一段代码
NSString *originStr = @"hongbao";
NSString *copyString = [originStr copy];
NSString *mutableCopyString = [originStr mutableCopy];
NSLog(@"\noriginStr----%p----value:%@",originStr,originStr);
NSLog(@"\ncopyString----%p----value:%@",copyString,copyString);
NSLog(@"\nmutableCopyString----%p----value:%@",mutableCopyString,mutableCopyString);
originStr = @"hongbaocui";
NSLog(@"\noriginStr----%p----value:%@----change",originStr,originStr);
NSLog(@"\ncopyString----%p----value:%@----change",copyString,copyString);
NSLog(@"\nmutableCopyString----%p----value:%@----change",mutableCopyString,mutableCopyString);
输出结果:
originStr----0x10ead6040----value:hongbao
copyString----0x10ead6040----value:hongbao
mutableCopyString----0x600001769dd0----value:hongbao
修改 源对象的值,副本对象不会改变
originStr----0x10ead60c0----value:hongbaocui----change //源对象地址已经改变
copyString----0x10ead6040----value:hongbao----change
mutableCopyString----0x600001769dd0----value:hongbao----change
由上面例子可以看出:源对象改变:地址变为:0x10ead60c0 副本的对象地址不变,copy地址为0x10ead6040 mutablecopy地址为:0x600001769dd0与之前相同
所以copy还有以下特点:
修改源对象的属性和行为,不会影响副本对象
修改副本对象的属性和行为,不会影响源对象
问题3 copy 一个可变的数组,会出现什么结果? 如下:
NSMutableArray *mutableArray1 = [NSMutableArray arrayWithObjects:@"3",@"4", nil];
NSLog(@"mutableArray1:%p---------%@",mutableArray1,mutableArray1);
NSMutableArray *copyArray1 = mutableArray1.copy;
NSLog(@"copyArray1:%p---------%@",copyArray1,copyArray1);
打印结果:
mutableArray1:0x600002b135a0---------(3,4)
copyArray1:0x60000256c7a0---------(3,4)
内存地址来看,地址改变。mutableArray1 为可变的,copyArray1 为不可变的,是通过copy 拷贝来的,mutableArray1指向可变的空间,copyArray1指向不可变的空间,所以copy 浅拷贝已经不适合原来指向的内存你空间,因此 copy从新开辟内存空间
问题4 用 copy 修饰 NSMutableArray @property (nonatomic, copy) NSMutableArray *myArray;,对myArray 赋值会有什么结果?
由问题3可知道,可以看出内存地址不一样,但是myArray 是不可变的数组。因为 myArray声明的时候是用 copy修饰,那么就限制了他为不可变的数组。
问题4 对属性strong对象进行copy操作,会开辟新内存空间吗?
不会
问题5 一个数组中包含属性,copy或者mutablecopy ,数组中的值会被copy或者mutablecopy吗?上代码:
NSMutableArray *array_cui = [NSMutableArray arrayWithCapacity:1.0];
HBTestTools *t1 = [[HBTestTools alloc] init];
[array_cui addObject:t1];
HBTestTools *t2 = [[HBTestTools alloc] init];
[array_cui addObject:t2];
NSLog(@"array_cui:%p----array_cui:--value--%@",array_cui,array_cui);
NSMutableArray *objarray = array_cui.copy;
NSLog(@"objarray:%p----array_cui:--value--%@",objarray,objarray);
NSMutableArray *objarray_mutableCopy = array_cui.mutableCopy;
NSLog(@"objarray_mutableCopy:%p----objarray_mutableCopy:--value--%@",objarray_mutableCopy,objarray_mutableCopy);
打印结果如下:
array_cui:0x6000010393e0----array_cui:--value--(
"<HBTestTools: 0x600001c5c740>",
"<HBTestTools: 0x600001c5c750>"
)
objarray:0x600001e08080----array_cui:--value--(
"<HBTestTools: 0x600001c5c740>",
"<HBTestTools: 0x600001c5c750>"
)
objarray_mutableCopy:0x600003cdfab0----objarray_mutableCopy:--value--(
"<HBTestTools: 0x600003099f40>",
"<HBTestTools: 0x600003099f30>"
)
由结果可以看出:
copy地址改变(查看问题3),数组中的对象地址并不改变
mutablecopy 地址同样改变,数组中的对象地址并不改变
总结
copy 修饰的或者赋值的为不可变的,只说copy 是地址copy 不准确,当为mutableCopy 对象进行copy操作时,会重新开辟内存空间
copy和mutableCopy 操作,修改源对象的属性和行为,不会影响副本对象;修改副本对象的属性和行为,不会影响源对象。
对象之间mutableCopy赋值,肯定会拷贝整个对象内存到另一块内存中
对象之间赋值之后,再改变,遵循互不影响的原则