深拷贝与浅拷贝
一般开发中经常会遇到数组拷贝或者字典拷贝等,而且很多时候需要对象拷贝,但是从来没有注意过copy与mutableCopy具体对于不同类型的数据拷贝的效果,只知道copy是浅拷贝,mutableCopy是深拷贝,今天一起看下是否是这么回事儿。
NSArray
NSArray在开发中是无处不在的,所以先看下对它的浅拷贝和盛拷贝效果。
通过以上代码以及打印结果可以看出,NSArray通过不同的方式拷贝,最终的得到的结论如下:
1、通过
copy拷贝是浅拷贝,只做了指针拷贝,本身NSArray类型的数据在内存中只存在一份,有两个指针指向它 2、通过mutableCopy拷贝是深拷贝,内存中存在两份NSArray类型的数据,各自都有一个指针指向内存中的数据
NSMutableArray
NSMutableArray在开发中是最常用的,特别是有列表数据的时候,所以看下NSMutableArray不同方式的拷贝,效果是怎样的。
通过以上代码以及打印结果可以看出,NSMutableArray通过不同方式的拷贝,最终得到如下结论:
1、通过
copy拷贝是深拷贝,但是可变数组经过copy拷贝出来后变成了不可变数组,内存中存在两份数据,一份是本身NSMutableArray类型的数据,一份是NSArray类型的数据 2、通过MutableCopy拷贝是深拷贝,并且拷贝出来的数据还是NSMutableArray类型的数据,在内存中存在两份,各自有一个指针指向
NSDictionary
NSDictionary 字典数据是开发中到处都有的,它的特色就是通过key-value存取。那么接下来看下NSDictionary通过不同的拷贝方式,结果又是如何呢?
通过以上代码以及打印结果可以看出,NSDictionary 通过不同的方式拷贝,最终的得到的结论如下:
1、通过
copy拷贝是浅拷贝,只做了指针拷贝,本身NSDictionary类型的数据在内存中只存在一份,有两个指针指向它 2、通过mutableCopy拷贝是深拷贝,内存中存在两份NSDictionary类型的数据,各自都有一个指针指向内存中的数据
NSMutableDictionary
NSMutableDictionary在开发中是最常用的,特别是有列表数据的时候,所以看下NSMutableDictionary 不同方式的拷贝,效果是怎样的。
通过以上代码以及打印结果可以看出,NSMutableDictionary通过不同方式的拷贝,最终得到如下结论:
1、通过
copy拷贝是深拷贝,但是可变数组经过copy拷贝出来后变成了不可变字典,内存中存在两份数据,一份是本身NSMutableDictionary类型的数据,一份是NSDictionary类型的数据 2、通过MutableCopy拷贝是深拷贝,并且拷贝出来的数据还是NSMutableDictionary类型的数据,在内存中存在两份,各自有一个指针指向
LGPerson
LGPerson在开发中也有需要对象实现拷贝操作,但是我们是需要深拷贝还是浅拷贝呢?这个问题先留着,先看下效果:
此处需要注意,如果我们需要对象具有拷贝功能,那么必须实现NSCopying或NSMutableCopy协议,这两个协议都是只有一个方法需要实现:- (nonnull id)copyWithZone:(nullable NSZone *)zone以及- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone。接下来看下具体实现:
@implementation LGPerson
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
LGPerson *p = [[[self class] allocWithZone:zone] init];
return p;
}
- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {
LGPerson *p = [[LGPerson alloc] init];
return p;
}
@end
此处没有写属性,但是无论有没有属性,对于对象来说都是深拷贝。我们可以通过上面打印得到验证。
总结
通过以上几个验证,我们可以得到以下几个结论:
1、对于系统的非容器类对象,如:NSString,如果是不可变对象,对对象进行拷贝操作,
copy就是浅拷贝,mutableCopy就是深拷贝。
2、对于系统的非容器类对象,如果是可变对象,如:NSMutableNSString,对对象进行拷贝操作,
copy就是深拷贝,但是拷贝出来的对象是个不可变的,mutableCopy就是深拷贝,类型也是也可变类型。
3、对于系统的容器类对象,如果是不可变对象,如:NSArray,对对象进行拷贝操作,
copy就是浅拷贝,mutableCopy就是深拷贝。
4、对于系统的容器类对象,如果是可变对象,如:NSMutableArray,对对象进行拷贝操作,
copy就是深拷贝,但是拷贝出来的对象是个不可变的,mutableCopy就是深拷贝,类型也是也可变类型。
5、对于用户自定义对象,无论是
copy还是mutableCopy都是深拷贝