美文网首页
深拷贝和浅拷贝以及使对象能够拷贝的条件

深拷贝和浅拷贝以及使对象能够拷贝的条件

作者: A维生素A | 来源:发表于2018-05-24 17:33 被阅读0次

    1、使对象具有拷贝功能

    在自定义的类里面实现NSCopying协议和NSMutableCopying协议,若没有实现这两个协议的话,在实例化对象后调用copy/mutableCopy会报错。

    为什么要使用copy?

    copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。copy属性表示两个对象内容相同,新的对象引用为1 ,与旧有对象的引用计数无关,旧的对象并没有变化。copy减少对象对上下文的依赖。copy过后的新对象会开辟新的内存空间。

    对于系统的非容器类对象(NSArray、NSMutableArray、NSDictionary、NSMutableDictionary等),可以认为,如果对一不可变对象复制,copy是指针复制(浅拷贝)而mutableCopy就是对象复制(深拷贝)。如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。

    copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制。引用计数每次+1。始终返回一个不可变对象。

    mutableCopy:始终是深复制,引用计数不改变。始终返回一个可变对象

    那么先让我们来看一看下数组类型的转换

    1、不可变对象→可变对象的转换:

           NSArray *arr1= [NSArray arrayWithObjects:@"1",@"2",@"3",@"4",nil];

         NSMutableArray *arr2=[arr1 mutableCopy];

    2、可变对象→不可变对象的转换:

        NSMutableArray *array1   = [NSMutableArray arrayWithObjects:@"a1",@"b1",@"c1",@"d1",nil];

           NSArray *array2=[ array1   Copy];

    3、可变对象→可变对象的转换(不同指针变量指向不同的内存地址)

           NSMutableArray *array1= [NSMutableArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

         NSMutableArray *array2=[array1 mutableCopy];

    通过上边的两个例子,我们可轻松的将一个对象在可变和不可变之间转换,并且这里不用考虑内存使用原则(即引用计数的问题)。没错,这就是深拷贝的魅力了。

    4、同类型对象之间的指针复制(不同指针变量指向同一块内存地址):

      a、

     NSMutableString *str1=[NSMutableString stringWithString:@"two day"];

       NSMutableString *str2=[str1  retain];

    b、

       NSArray *array1= [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

       NSArray *str2=[array1 Copy];

     通俗的讲,多个指针同时指向同一块内存区域,那么这些个指针同时拥有对该内存区的所有权。所有权的瓜分过程,这时候就要用到浅拷贝了。

    可以把上面所有的问题则简化如下:

    什么时候用到深浅拷贝?

    深拷贝(mutableCopy)是在要将一个对象从可变(不可变)转为不可变(可变)或者将一个对象内容克隆一份时用到;

    浅拷贝(copy)是在要复制一个对象的指针时用到。

    对可变对象使用 copy 和MutableCopy 都会拷贝一个新的对象出来,即,copy 和 mutableCopy 都是深拷贝;

    对不可变对象使用 copy, 新拷贝出来的对象地址和被拷贝对象地址一致 

    对不可变对象使用 mutableCopy 新拷贝出来的对象和被拷贝的对象内存地址发生变化, 

    所以对不可变对象 copy 就是浅拷贝,mutableCopy 就是深拷贝. 

    相关文章

      网友评论

          本文标题:深拷贝和浅拷贝以及使对象能够拷贝的条件

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