OC中的深浅复制

OC中的复制

什么是复制?

    复制是一种拷贝,无论是对对象指针的拷贝(浅拷贝),还是对对象内容的拷贝(深拷贝),其最终实现的是对对象的拷贝。

 

复制的条件?

<NSCoping>protocol

凡是遵循NSCoping协议的对象都可以进行copy。

NSCoping协议中声明:

-   (id)copyWithZone:(NSZone *)zone;

-   (id)copyWithZone:(NSZone *)zone{

     NSString *name=[self.name copy];//这里假如self.name是可变字符串的话,那么执行的就是深复制,否则执行的是浅复制(原因见下面分析)。

     Person *p=[[Person alloc] initWithName:name age:self.age];//将以前的值拷贝过来,返回到一个新的空间

-   }

 

 

什么时候使用复制?

当我们需要获取一个容器的内容的时候,我们可以采取复制方法。至于是通过指针来访问拷贝前对象的内容(浅拷贝)还是通过指针来访问新空间的内容(深拷贝),取决于被拷贝对象的允许度以及我们采取的方法力度。

为什么要用复制?

深复制可以让我们在不破坏之前对象内容的情况下,在新空间获得跟之前等值的内容,并且可以对新空间的内容进行我们必要的处理。

浅复制我们如果改变指针指向内容的时候,就容易变动之前对象内容,不安全。

 

复制的方法与特点?

苹果官网解析图


Shallowcopying:

  对象A 指针textColor指向textColor的内容,经过shallow copy后,对象B中指针也指向了textColor。

  在浅拷贝中,由于同一个对象增加了一个指针,因此retain count增加1.

 

Deep copying:

  可以看出是重新开辟了一个空间来盛装textColor指向的内容,同时用一个新的指针指向这个新的内容。

 

分类说明:

(1)对于字符串的拷贝

NSString

NSString *str3=[NSString stringWithFormat:@"zhangsan"];

[str3 retain];//

NSLog(@"%lu",[str3 retainCount]);//1

NSString *str4=[str3 copy];//2

NSLog(@"%lu %p %p",[str3 retainCount],str3,str4);//两个地址相同,说明实现的是浅拷贝,计数增加1.

经过检测,无论接收数组是可变的还是不可变的,对于不可变字符串的拷贝都是浅拷贝。

 

MutableString

NSMutableString *str1=[NSMutableString stringWithString:@"wangliang"];

NSLog(@"%lu",[str1 retainCount]);

// NSLog(@"%lu",[str5 retainCount]);//这里str5没有开辟空间,因此不存在计数。

NSMutableString *str2=[str1 copy];//拷贝

NSLog(@"%lu %lu",[str1 retainCount],[str2 retainCount]);//1 1

NSLog(@"%@ %p %p",str2,str2,str1);//wangliang地址相同
[str1 release];//这里str1本身的计数为1,如果再进行release就会dealloc,出现crash。

经过测试,无论是用可变字符串还是不可变来接收拷贝返回值,可变字符串拷贝都是深拷贝,拷贝后retaincount数值不变,地址不一样。

 

 

(2)对于数组的拷贝

NSArray

NSArray *arr=@[@"zhangsan",@"lisi",@"wangwu"];

NSArray *arr1=[arr copy];//此时arr1的计数也为2

NSLog(@"%lu",[arr retainCount]);//2
NSLog(@"%p %@ %p %@",arr,arr,arr1,arr);//打印出来的两个数组的内容相同,说明经过测试:已经实现了拷贝,但是两个数组的指针也相同,说明不可变数组实现的只是浅拷贝。

 

NSutableArray

NSMutableArray *arrM=[[NSMutableArray alloc] initWithObjects:@"zhangsan",@"lisi",@"wangwu", nil];

NSArray *arrm=[arrM copy];

NSLog(@"%p %p",arrM,arrm);

经过测试,无论是用可变数组还是不可变数组来接收拷贝返回值,可变数组拷贝都是深拷贝,拷贝后retaincount数值不变,地址不一样。

 

总结:

    对于不可变容器的拷贝,只能采用retain方式进行拷贝,也就是对不可变容器进行指针的拷贝。对于可变容器的拷贝,进行的都是深拷贝,拷贝的过程是先创建一个空间,然后将拷贝值放入创建的新空间中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值