copy与mutableCopy区别,strong和copy的使用

本篇文章主要讲两个知识点:1.深拷贝与浅拷贝 2.NSArray和NSMutaleArray应该用copy还是stong修饰。

一、我们先来分析深拷贝(返回一个对象,一个新的指针指向一个新的内容)与浅拷贝(返回一个对象,一个新的指针指向旧的内容)。

这里面分集合类型(NSArray、NSDictionary、NSSet等类型)与非集合类型(NSString等类型)。

1.分析NSString不可变类型:

  NSLog(@"非集合不可变类型进行Copy与MutableCopy");
   NSString * orginStr = @"原始数据";
   NSString * copyStr = [orginStr copy];
   NSMutableString * mutableStr = [orginStr mutableCopy];
   NSLog(@"内存地址-->orginStr:%p  copyStr:%p  mutableStr:%p",orginStr,copyStr,mutableStr);
   NSLog(@"内容orginStr:%@  copyStr:%@  mutableStr:%@",orginStr,copyStr,mutableStr);

然后看下打印结果:

 

 

屏幕快照 2017-09-01 下午11.28.34.png

对NSString类型进行copy,内存地址没有变化,没产生新对象;mutable时内存地址变了,产生了新对象。
2.分析NSArray不可变类型:

   NSLog(@"集合不可变类型进行Copy与MutableCopy");
    NSArray * orginArray = [NSArray arrayWithObjects:@"小红",@"小明",@"小李",nil];
    NSArray * copyArray = [orginArray copy];
    NSMutableArray * mutableCopyArray = [orginArray mutableCopy];
    NSLog(@"内存地址-->orginArray:%p  copyArray:%p  mutableCopyArray:%p",orginArray,copyArray,mutableCopyArray);

看下打印结果:

 

对NSArray类型进行copy,内存地址没有变化,没产生新对象;mutable时内存地址变了,产生了新对象。

3.分析NSMutableString可变类型

 NSLog(@"非集合可变类型进行Copy与MutableCopy");
    NSMutableString * orginStr = [[NSMutableString alloc]initWithString:@"原始数据"];
    NSString * copyStr = [orginStr copy];
    NSMutableString * mutableStr = [orginStr mutableCopy];
    NSLog(@"内存地址-->orginStr:%p  copyStr:%p  mutableStr:%p",orginStr,copyStr,mutableStr);
    NSLog(@"内容orginStr:%@  copyStr:%@  mutableStr:%@",orginStr,copyStr,mutableStr);

看下打印结果:

 

 

对NSMutableString类型进行copy,内存地址没有变化,没产生新对象;mutable时内存地址变了,产生了新对象。

4.分析NSMutableArray可变类型

  NSLog(@"集合可变类型进行Copy与MutableCopy");
    NSArray * orginArray = [NSMutableArray arrayWithObjects:@"小红",@"小明",@"小李", nil];
    
    NSArray * copyArray = [orginArray copy];
    NSMutableArray * mutableCopyArray = [orginArray mutableCopy];
    NSLog(@"内存地址-->orginArray:%p  copyArray:%p  mutableCopyArray:%p",orginArray,copyArray,mutableCopyArray);

看下打印结果

 

以上四种情况,我们可以得到这样结论:
A.不可变类型(不管是集合还是非集合),copy结果,不产生新对象,浅拷贝;
不可变类型(不管是集合还是非集合),mutableCopy结果,产生新对象,深拷贝.
B.可变类型(不管是集合还是非集合),copy结果,产生新对象,深拷贝;
可变类型(不管是集合还是非集合),mutableCopy结果,产生新对象,深拷贝.

二、说完拷贝与深拷贝我们来研究下copy与strong对不可变类型(NString、NSArray、NSSet),以及对可变类型(NSMutableString、NSMutableArray、NSMutableSet)的影响。
这是声明的一些属性:

1.copy与strong对不可变类型(NString、NSArray、NSSet)影响:

 

先看对不可变类型(NString、NSArray、NSSet)的影响:

 NSLog(@"NSArray的修饰词测试");
    NSMutableArray * orginMutableArray = [NSMutableArray arrayWithObjects:@"1",@"2",@"3", nil];
    self.copydArray = orginMutableArray;
    self.strongArray = orginMutableArray;
    NSLog(@"内存地址-->orginMutableArray:%p  self.copydArray:%p  self.strongMutableArray:%p",orginMutableArray,self.copydArray,self.strongArray );
     NSLog(@"内容-->orginMutableArray:%@  self.copydArray:%@  self.strongMutableArray:%@",orginMutableArray,self.copydArray,self.strongArray );
    
    [orginMutableArray removeLastObject];
    NSLog(@"删除一个元素后内容-->orginMutableArray:%@  self.copydArray:%@  self.strongMutableArray:%@",orginMutableArray,self.copydArray,self.strongArray );

再看下打印结果

 

当原始数组删除一个元素后,用strong修饰的array也删除一个,而copy修饰的却不变。NSarray本来就应该是不变的,所以对不可变类型(NString、NSArray、NSSet),要用copy修饰。
2.copy与strong对对可变类型(NSMutableString、NSMutableArray、NSMutableSet)的影响:

NSLog(@"NSMutableArray的修饰词测试");
    NSMutableArray * orginMutableArray = [NSMutableArray arrayWithObjects:@"1",@"2",@"3", nil];
    self.copydMutableArray = orginMutableArray;
    self.strongMutableArray = orginMutableArray;
    NSLog(@"内存地址-->orginMutableArray:%p  self.copydMutableArray:%p  self.strongMutableArray:%p",orginMutableArray,self.copydMutableArray,self.strongMutableArray);
    
    [self.strongMutableArray removeLastObject];
    /**
      这里会出现闪退
      [self.copydMutableArray removeLastObject];
     */

这里当我们用copy修饰可变类型(NSMutableString、NSMutableArray、NSMutableSet)时,竟然崩溃了。因为当用copy修饰后,NSMutaleArray由可变类型变成了不可变类型,而NSArray并没有增、删元素的方法,所以崩溃。因此,可变类型(NSMutableString、NSMutableArray、NSMutableSet),要用strong修饰。

所以我们得出结论:
A.对不可变类型(NString、NSArray、NSSet),要用copy修饰;
B.可变类型(NSMutableString、NSMutableArray、NSMutableSet),要用strong修饰;
C.用copy还是strong修饰一个属性时,与深拷贝浅拷贝不要混为一谈了,是两码事。

最后,写下本文所得到的五个结论:
1.不可变类型(不管是集合还是非集合),copy结果,不产生新对象,浅拷贝;
不可变类型(不管是集合还是非集合),mutableCopy结果,产生新对象,深拷贝.
2.可变类型(不管是集合还是非集合),copy结果,产生新对象,深拷贝;
可变类型(不管是集合还是非集合),mutableCopy结果,产生新对象,深拷贝.
3.对不可变类型(NString、NSArray、NSSet),要用copy修饰;
4.可变类型(NSMutableString、NSMutableArray、NSMutableSet),要用strong修饰;
5.用copy还是strong修饰一个属性时,与深拷贝浅拷贝不要混为一谈了,是两码事。

本文有用到https://www.zybuluo.com/MicroCai/note/50592,以及http://blog.csdn.net/winzlee/article/details/51752354两篇博客的知识点。

本文Demo地址:https://github.com/zhangxistudy11/KnowledgeSummaryOfObjectC
文章有不合理之处,以及代码不合理的地方,请各位读者及时指出。如果给你带来新的认知和便利,欢迎点赞!



作者:码工人生
链接:https://www.jianshu.com/p/c39ffd45bc7f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

posted @   brave-sailor  阅读(77)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
历史上的今天:
2015-04-01 Android Animation学习(六) View Animation介绍
2015-04-01 Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
2015-04-01 Android Animation学习(四) ApiDemos解析:多属性动画
2015-04-01 Android Animation学习(三) ApiDemos解析:XML动画文件的使用
2015-04-01 Android Animation学习(二) ApiDemos解析:基本Animatiors使用
2015-04-01 Android Animation学习(一) Property Animation介绍
2015-04-01 Android Animation动画(很详细)
点击右上角即可分享
微信分享提示