Object-C 中strong和copy的区别

strong与copy的区别

  参考网上同行的结论 strong与copy的区别最根本的原因就是setter方法的实现不一样,参考博客:https://www.cnblogs.com/AlvinCrash/p/5379455.html 具体如下:

  1. strong对应的setter方法,是将_property先release(_property release),然后将参数retain(property retain),最后是_property = property。
  2. 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

更多优质文章,可以微信扫码关注:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/HHL110120/article/details/89054003