手机app制作网站模板,软件开发是什么职业,湖北营销型网站建设,网站前端工程师【OC学习-26】对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝 对象的拷贝分为浅拷贝和深拷贝#xff0c;浅拷贝就是只拷贝对象#xff0c;但是属性不拷贝#xff0c;拷贝出来的对象和原来的对象共用属性#xff0c;即指向同一个属性地址。深拷贝则相当于不仅拷贝了一个… 【OC学习-26】对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝 对象的拷贝分为浅拷贝和深拷贝 浅拷贝就是只拷贝对象但是属性不拷贝拷贝出来的对象和原来的对象共用属性即指向同一个属性地址。 深拷贝则相当于不仅拷贝了一个对象还拷贝了它的属性即完全是两个东西只不过内容相同而已。 拷贝用到协议如果这个类创建对象后这个对象要被拷贝那么这个类就需要用到拷贝协议分两种NSCopying和NSMutableCopying相当于一个是拷贝另一个是拷贝后可修改。 1浅拷贝的案例。有一个Person类它创建一个person1对象后用person1再拷贝一个person2出来。 //Person类的Person.h文件
#import Foundation/Foundation.h
//因为这个类要支持拷贝所以需要引入拷贝协议有两种后一种拷贝后可修改
interface Person : NSObjectNSCopying,NSMutableCopying
property(nonatomic,copy) NSString* name; property(nonatomic,retain) NSNumber* age; end //这是Person.m文件
#import Person.h
implementation Person
//这是系统函数可以直接拷贝过来 - (id)copyWithZone:(NSZone *)zone{ Person *person[[[self class]allocWithZone:zone]init]; //默认格式 person.name_name; //浅拷贝就是直接赋值即可 person.age_age; //浅拷贝就是直接赋值即可 return person; } end //main.m文件
#import Foundation/Foundation.h
#import Person.h//记得引入头文件
int main(int argc, const char * argv[])
{autoreleasepool { Person *person1[[Person alloc]init]; person1.namejack; person1.age18; Person *person2[person1 copy]; NSLog(%p,%p,person1,person2);//输入两个对象地址不同 NSLog(%p,%p,person1.age,person2.age);//输出两个对象的属性地址相同 } return 0; } 结果 0x1002036f0,0x100200330 //不同
0x1227,0x1227 //相同 2深拷贝的案例。 按道理是只需要把Person.m里面的赋值语句改成下面的样子就能实现深拷贝 person.name[_name copy];
person.age[_age copy]; 但是因为cocoa优化过了所以有如下规则 a如果是Foundation框架里的不可变对象就是ArrayNSString等创建的对象直接用copy来拷贝相当于retain也就是属性还是同一个 b如果是用mutableCopy来拷贝不管是可变还是不可变对象属性神马的都直接拷贝了一份即真正意义上得拷贝它拷贝出来的对象统统都是可变的 c如果是可变对象我们用copy也能实现真正意义上的拷贝但是拷贝出来的对象是不可变的。 所以我们拿name实验因为age没有mutableCopy实现语句的修改 person.name[_name mutableCopy]
person.age[_age copy]; 然后再输出person1和person2的name属性的地址发现就不同了。 总结 浅拷贝和深拷贝在实际项目中不常用可以做一般了解。 OC深浅复制 浅 复 制在复制操作时对于被复制的对象的每一层复制都是指针复制。 深 复 制在复制操作时对于被复制的对象至少有一层复制是对象复制。 完全复制在复制操作时对于被复制的对象的每一层复制都是对象复制。 注1、在复制操作时对于对象有n层是对象复制我们可称作n级深复制此处n应大于等于1。 2、对于完全复制如何实现目前通用的办法是迭代法和归档这里后续是否添加视情况而定 暂时不做讲解。 3、指针复制俗称指针拷贝对象复制也俗称内容拷贝。 retain始终是浅复制。引用计数每次加一。返回对象是否可变与被复制的对象保持一致。 copy对于可变对象为深复制引用计数不改变;对于不可变对象是浅复制 引用计数每次加一。始终返回一个不可变对象。 mutableCopy始终是深复制引用计数不改变。始终返回一个可变对象。 不可变对象值发生改变其内存首地址随之改变。 可变对象无论值是否改变其内存首地址都不随之改变。 引用计数为了让使用者清楚的知道该对象有多少个拥有者即有多少个指针指向同一内存地址。 亲爱的读者朋友下面是我用于验证的详细代码。对于验证还能得出什么结论我希望朋友们能自己多多发掘一下。这里只做以上几点总结。对于本文有任何疑问请与我联系欢迎指出本文不足的地方谢谢 #importFoundation/Foundation.h int main (int argc, const char * argv[]) { autoreleasepool { //第一种非容器类不可变对象 NSString *str1one day; printf(n初始化赋值引用计数为::::%lu,str1.retainCount); NSString *strCopy1[str1 retain]; printf(n继续retain引用计数为:::%lu,str1.retainCount); NSString *strCopy2[str1 copy]; printf(n继续copy后引用计数为::::%lu,str1.retainCount); NSString *strCopy3[str1 mutableCopy]; printf(n继续mutableCopy后为:::%lun,str1.retainCount); printf(n非容器类不可变对象n原始地址::::::::::%p,str1); printf(nretain复制::::::::%p,strCopy1); printf(ncopy复制::::::::::%p,strCopy2); printf(nmutableCopy复制:::%p,strCopy3); //这里说明该类型不存在引用计数的概念 // 初始化赋值引用计数为18446744073709551615 // 继续retain引用计数为18446744073709551615 // 继续copy后引用计数为18446744073709551615 // 继续mutableCopy后为18446744073709551615 //非容器类不可变对象 //原始地址::::::::::0x1000033d0 //retain复制::::::::0x1000033d0//浅复制 //copy复制::::::::::0x1000033d0//浅复制 //mutableCopy复制:::0x10010c420//深复制 printf(n); //第二种容器类不可变数组 NSArray *array1 [NSArray arrayWithObjects:a,b,c,d,nil]; printf(n初始化赋值引用计数为::::::::::::%lu,array1.retainCount); NSArray *arrayCopy1 [array1 retain]; printf(n继续retain后引用计数为:::::::::%lu,array1.retainCount); NSArray *arrayCopy2 [array1 copy]; printf(n继续copy后引用计数为:::::::::::%lu,array1.retainCount); NSArray *arrayCopy3 [array1 mutableCopy]; printf(n继续mutableCopy后引用计数为::::%lun,array1.retainCount); printf(n容器类不可变数组n原始地址::::::::::%ptt%p,array1,[array1 objectAtIndex:1]); printf(nretain复制::::::::%pt%p,arrayCopy1,[arrayCopy1 objectAtIndex:1]); printf(ncopy复制::::::::::%pt%p,arrayCopy2,[arrayCopy2 objectAtIndex:1]); printf(nmutableCopy复制:::%pt%p,arrayCopy3,[arrayCopy3 objectAtIndex:1]); //初始化赋值引用计数为::::::::::::1 //继续retain后引用计数为:::::::::2 //继续copy后引用计数为:::::::::::3 //继续mutableCopy后引用计数为::::3 //容器类不可变数组 //原始地址::::::::::0x10010c6b0 0x100003410 //retain复制::::::::0x10010c6b0 0x100003410//浅复制 //copy复制::::::::::0x10010c6b0 0x100003410//浅复制 //mutableCopy复制:::0x10010c760 0x100003410//深复制 printf(n); //第三种非容器类可变对象 NSMutableString *str2[NSMutableString stringWithString:two day]; printf(n初始化赋值引用计数为::::::::::::%lu,str2.retainCount); NSMutableString *strCpy1[str2 retain]; printf(n继续retain后引用计数为:::::::::%lu,str2.retainCount); NSMutableString *strCpy2[str2 copy]; printf(n继续copy后引用计数为:::::::::::%lu,str2.retainCount); NSMutableString *strCpy3[str2 mutableCopy]; printf(n继续mutableCopy后引用计数为::::%lun,str2.retainCount); printf(n非容器类可变对象n原始地址::::::::::%p,str2); printf(nretin复制::::::::%p,strCpy1); printf(ncopy复制::::::::::%p,strCpy2); printf(nmutableCopy复制:::%p,strCpy3); //初始化赋值引用计数为::::::::::::1 //继续retain后引用计数为:::::::::2 //继续copy后引用计数为:::::::::::2 //继续mutableCopy后引用计数为::::2 //非容器类可变对象 //原始地址::::::::::0x10010c560 //retain复制::::::::0x10010c560//浅复制 //copy复制::::::::::0x100102720//深复制 //mutableCopy复制:::0x10010c880//深复制 printf(n); //第四种容器类可变数组 NSMutableArray *array2 [NSMutableArrayarrayWithObjects:aa,bb,cc,dd,nil]; printf(n初始化赋值引用计数为::::::::::%lu,array2.retainCount); NSMutableArray *arrayCpy1 [array2 retain]; printf(n继续retain后引用计数为:::::::%lu,array2.retainCount); NSMutableArray *arrayCpy2[array2 copy]; printf(n继续copy后引用计数为:::::::::%lu,array2.retainCount); NSMutableArray *arrayCpy3 [array2 mutableCopy]; printf(n继续mutableCopy后引用计数为::%lun,array2.retainCount); printf(n容器类可变数组n原始地址:::::::::::%pt%p,array2,[array2 objectAtIndex:1]); printf(nretain复制:::::::::%pt%p,arrayCpy1,[arrayCpy1 objectAtIndex:1]); printf(ncopy复制:::::::::::%pt%p,arrayCpy2,[arrayCpy2 objectAtIndex:1]); printf(nnmutableCopy复制:::%pt%p,arrayCpy3,[arrayCpy3 objectAtIndex:1]); //初始化赋值引用计数为::::::::::1 //继续retain后引用计数为:::::::2 //继续copy后引用计数为:::::::::2 //继续mutableCopy后引用计数为::2 //容器类可变数组 //原始地址:::::::::::0x10010e6c0 0x1000034b0 //retain复制:::::::::0x10010e6c0 0x1000034b0//浅复制 //copy复制:::::::::::0x10010e790 0x1000034b0//深复制 //nmutableCopy复制:::0x10010e7c0 0x1000034b0//深复制 } return 0; } 转载于:https://www.cnblogs.com/iOS-mt/p/4121583.html