前言
今天看到一篇博客,这篇博客说copy和mutableCopy都是浅拷贝,当时我就震惊了,跟我的认知不一样啊。本着实践出真知的精神,我就去试了一下,一试就发现我之前对copy和mutableCopy的认知是错误的(震惊!
在实验之前我就直接放上结论吧。
容器这个对象遵循网上博客所说的不同情况下的copy和mutableCopy会有深拷贝或浅拷贝的效果,如下表:
类型 | copy | mutableCopy |
---|---|---|
NSArray | 浅拷贝 | 深拷贝 |
NSMutableArray | 深拷贝 | 深拷贝 |
但是!!!
容器内的对象是不会遵循这个上面这个原则的,容器内的对象无论如何都是浅拷贝,他们都指向同一块内存地址。因为容器内的对象都不会被深拷贝,所以我的结论是容器类无论是copy还是mutablCopy都是浅拷贝
。
实验
我们写一个Test看看可变容器copy之后,不可变容器内的对象内存地址有没有改变,这里的写法按照之前的认知会认为tempArray是self.mArray的深拷贝之后的容器对象。
@property (nonatomic, strong) NSMutableArray *mArray;
@property (nonatomic, copy) NSArray *array;
Element *element = [[Element alloc] init];
element.str = @"123";
self.mArray = @[element].mutableCopy;
Element *mElement = [self.mArray firstObject];
NSLog(@"array:%p, element:%p, content:%@", self.mArray, mElement, mElement.str);
NSArray *tempArray = self.mArray.copy;
Element *tempElement = [tempArray firstObject];
tempElement.str = @"321";
NSLog(@"array:%p, element:%p, content:%@", tempArray, tempElement, tempElement.str);
NSLog(@"array:%p, element:%p, content:%@", self.mArray, mElement, mElement.str);
效果是:
array:0x600003616df0, element:0x600003a7cca0, content:123
array:0x600003a6c0c0, element:0x600003a7cca0, content:321
array:0x600003616df0, element:0x600003a7cca0, content:321
通过第1和第2行的输出我们可以发现深拷贝的只有容器这个对象,因为他的内存地址改变了。但是内部元素的内存地址不变,尝试给这个容器的第一个元素的属性赋新的值,通过第三行可以看到,self.mArray里第一个元素的属性也跟着变了(废话)。
mutableCopy也是一样的效果,这里就不试了,有兴趣的朋友可以自己试一下。
最后
所以要说深拷贝的话只有容器这个对象能深拷贝,容器对象的深拷贝能解决的问题只有内部元素的数量不会随着其拷贝容器对象的改变而改变。这个话说起来很变扭,举个例子:
self.mArray = @[@1, @2, @3].mutableCopy;
NSArray *array = self.mArray.copy;
[self.mArray addObject: @4];
这个时候array是不会随着mArray的改变而改变的。
网友评论