美文网首页
深拷贝与浅拷贝

深拷贝与浅拷贝

作者: KG丿夏沫 | 来源:发表于2021-06-09 09:03 被阅读0次

    深拷贝与浅拷贝

    一般开发中经常会遇到数组拷贝或者字典拷贝等,而且很多时候需要对象拷贝,但是从来没有注意过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都是深拷贝

    相关文章

      网友评论

          本文标题:深拷贝与浅拷贝

          本文链接:https://www.haomeiwen.com/subject/koeleltx.html