strong与copy的区别
参考网上同行的结论 strong与copy的区别最根本的原因就是setter方法的实现不一样,参考博客:https://www.cnblogs.com/AlvinCrash/p/5379455.html 具体如下:
- strong对应的setter方法,是将_property先release(_property release),然后将参数retain(property retain),最后是_property = property。
- copy对应的setter方法,是将_property先release(_property release),然后拷贝参数内容(property copy),创建一块新的内存地址,最后_property = property。
strong和copy的区别在在有些数据类型上可以体现出来,有些数据类型上体现不出来
用了Object-C也好多年了,对于strong和copy的了解一直不太彻底,在用的过程中对于哪些数据类型,strong和copy的效果是一样的,哪些数据类型strong和copy的效果是不一样的。这些数据的界限不是特别清楚。参考网上同行的博客,大家也并没有对这一块做出深入的挖掘。为了方便区分理解,我这边把数据类型按照分为容器类型的数据,和非容器类型数据。
保存在栈和堆上数据的区别
我这边以NSString类型和NSMutableString类型进行验证分析。NSString类型的数据存储在栈上,由系统管理存储空间的分配与回收,而NSMutableString数据类型存储在堆上,由开发者管理存储空间的分配与回收。根据这位同行的博客https://www.jianshu.com/p/25841071c813
NSString类型操作如下:
@property (nonatomic,strong) NSString *name;
@property (nonatomic,copy) NSString *address;
NSString *name = @"jack";
NSString *address = @"Beijing";
NSLog(@"name1 %p",name);
NSLog(@"address1 %p",address);
self.name = name;
self.address = address;
NSLog(@"name2 %p",self.name);
NSLog(@"address2 %p",self.address);
self.name = @"lisa";
self.address = @"nanjing";
NSLog(@"name3 %p",self.name);
NSLog(@"address3 %p",self.address);
运行结果如下:
可以发现对NSString类型的数据执行copy和strong操作后self.name与name,self.address 与address指向的地址相同,copy与strong操作效果一致,当改变self.name,self.address的值时,发现他们的地址都发生了改变。根据以上信息,我们可以分析出来对于保存在栈上的数据,无论执行copy或者strong操作本质上都是执行的strong操作,当这些指针指向的数据发生改变时,系统会自动分批内存空间用来储存改变之后的值。
NSMutableString 操作如下:
@property (nonatomic,strong) NSMutableString *name;
@property (nonatomic,copy) NSMutableString *address;
NSMutableString *name = [[NSMutableString alloc] initWithString:@"jack"];
NSMutableString *address = [[NSMutableString alloc] initWithString:@"beiing"];
NSLog(@"name1 %p ",name);
NSLog(@"address1 %p",address);
self.name = name;
self.address = address;
NSLog(@"name2 %p ",name);
NSLog(@"address2 %p",address);
[name appendString:@"A"];
[address appendString:@"B"];
NSLog(@"name3 %p ",name);
NSLog(@"address3 %p",address);
NSLog(@"name4 %p ",self.name);
NSLog(@"address4 %p",self.address);
[self.name appendString:@"C"];
NSLog(@"name5 %p",self.name);
[self.address appendString:@"D"];
NSLog(@"address5 %p",self.address);
运行结果如下:
通过分析name3与name4的地址,可以看出NSMutableString执行strong操作后,并没有被分配新的内存地址,而是指向原来的内存地址;address3与address4的地址,可以看出NSMutableString执行copy操作后,分配了一个新的内存地址;分析address4与address5时我们发现出现了崩溃,根据崩溃信息我们可以推断,NSMutableString执行copy操作后新分配的一个地址是系统默认分配的,数据保存在栈上应该是属于NSString类型,不能够执行拼接的方法,因此产生了崩溃。
深copy与浅copy的区别
<1>浅拷贝:就相当于retain,只copy了一个对象的引用,和本身是同一个对象,就相当于影子。
<2>深拷贝:从新开辟了一块内存空间,用来存放原来对象里面的东西,这个时候,copy出来的对象和原来的对象不是同一个对象,他们的内容一样,就相当于克隆人。
<3>拷贝出来的的对象是什么类型取决于使用什么拷贝。
具体如下:
1)不可变对象执行copy操作,是浅copy
2)不可变对象执行mutableCopy操作,是深copy
3)可变对象执行copy操作,是浅copy
4)可变对象执行mutableCopy操作,是深copy操作
参考博客:https://www.cnblogs.com/dingjiwoniu-blogs/p/5141687.html
更多优质文章,可以微信扫码关注: