深拷贝与浅拷贝

深拷贝与浅拷贝

一般开发中经常会遇到数组拷贝或者字典拷贝等,而且很多时候需要对象拷贝,但是从来没有注意过copy与mutableCopy具体对于不同类型的数据拷贝的效果,只知道copy是浅拷贝,mutableCopy是深拷贝,今天一起看下是否是这么回事儿。

NSArray

NSArray在开发中是无处不在的,所以先看下对它的浅拷贝和盛拷贝效果。
20210607001.png

通过以上代码以及打印结果可以看出,NSArray通过不同的方式拷贝,最终的得到的结论如下:

1、通过copy拷贝是浅拷贝,只做了指针拷贝,本身NSArray类型的数据在内存中只存在一份,有两个指针指向它
2、通过mutableCopy拷贝是深拷贝,内存中存在两份NSArray类型的数据,各自都有一个指针指向内存中的数据

NSMutableArray

NSMutableArray在开发中是最常用的,特别是有列表数据的时候,所以看下NSMutableArray不同方式的拷贝,效果是怎样的。

20210607002.png

通过以上代码以及打印结果可以看出,NSMutableArray通过不同方式的拷贝,最终得到如下结论:

1、通过copy拷贝是深拷贝,但是可变数组经过copy拷贝出来后变成了不可变数组,内存中存在两份数据,一份是本身NSMutableArray类型的数据,一份是NSArray类型的数据
2、通过MutableCopy拷贝是深拷贝,并且拷贝出来的数据还是NSMutableArray类型的数据,在内存中存在两份,各自有一个指针指向

NSDictionary

NSDictionary 字典数据是开发中到处都有的,它的特色就是通过key-value存取。那么接下来看下NSDictionary通过不同的拷贝方式,结果又是如何呢?

20210607003.png

通过以上代码以及打印结果可以看出,NSDictionary 通过不同的方式拷贝,最终的得到的结论如下:

1、通过copy拷贝是浅拷贝,只做了指针拷贝,本身NSDictionary 类型的数据在内存中只存在一份,有两个指针指向它
2、通过mutableCopy拷贝是深拷贝,内存中存在两份NSDictionary 类型的数据,各自都有一个指针指向内存中的数据

NSMutableDictionary

NSMutableDictionary在开发中是最常用的,特别是有列表数据的时候,所以看下NSMutableDictionary 不同方式的拷贝,效果是怎样的。

20210607004.png

通过以上代码以及打印结果可以看出,NSMutableDictionary通过不同方式的拷贝,最终得到如下结论:

1、通过copy拷贝是深拷贝,但是可变数组经过copy拷贝出来后变成了不可变字典,内存中存在两份数据,一份是本身NSMutableDictionary类型的数据,一份是NSDictionary类型的数据
2、通过MutableCopy拷贝是深拷贝,并且拷贝出来的数据还是NSMutableDictionary类型的数据,在内存中存在两份,各自有一个指针指向

LGPerson

LGPerson在开发中也有需要对象实现拷贝操作,但是我们是需要深拷贝还是浅拷贝呢?这个问题先留着,先看下效果:

20210607005.png

此处需要注意,如果我们需要对象具有拷贝功能,那么必须实现NSCopyingNSMutableCopy协议,这两个协议都是只有一个方法需要实现:- (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都是深拷贝

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享