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

2018-05-24  本文已影响0人  A维生素A

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 就是深拷贝. 

上一篇 下一篇

猜你喜欢

热点阅读