(0087)iOS开发之NSString属性为什么要用copy来修饰?

2023-12-03 20:32

本文主要是介绍(0087)iOS开发之NSString属性为什么要用copy来修饰?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个问题既是一个面试题,也是开发中经常遇到的问题,NSString 属性到底用copy 还是 strong ?其实如果明白的两者的区别也就不会疑惑了,其实都可以,只是如果你不明白两者的实质的区别,有可能会出现难以发现的异常。但是我们遇到的又很少所有经常用哪个都行,但是不知道有何区别,在此我实际验证一下。记录这个经常模糊不清的问题。

 

1.快速搭建一个demo

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.NSLog(@"\n");// 验证不可变对象NSString[self test];// 验证可变对象NSMutableString// [self test22];// 如果用NSString赋值的话strong和copy(此刻是浅拷贝)是没有区别的// 如果用NSMutableString赋值的话strong没有只是增加了str1的计数器,并没有开辟新的内存// copy的话开辟了新的内存,对string的内容进行修改的话,strong的字符串内容改变了,而copy的并没有改变// 如果需要改变的话可以用strong,如果不需要改变的话用copy// 所以属性指向可变对象时应注意;
}
- (void)test{NSString *string = [NSString stringWithFormat:@"测试文字"];//注释1self.strongStr = string;self.copyssStr = string;NSLog(@"String:%@   strongStr:%@   copyssStr:%@",string,self.strongStr,self.copyssStr);NSLog(@"String   : %p, %p", string, &string);NSLog(@"Strong属性: %p, %p",_strongStr, &_strongStr);NSLog(@"Copy  属性: %p, %p",_copyssStr, &_copyssStr);NSLog(@"\n");string = @"我变了,你没变";NSLog(@"我变 String:%@   strongStr:%@   copyssStr:%@",string,self.strongStr,self.copyssStr);NSLog(@"我变 String   : %p, %p", string, &string);NSLog(@"我变 Strong属性: %p, %p",_strongStr, &_strongStr);NSLog(@"我变 Copy  属性: %p, %p",_copyssStr, &_copyssStr);// NSString总结:用NSString赋值的话strong和copy(此刻是浅拷贝)是没有区别的;从新赋值,相当于指向了新的一个对象,string指向变了,而strong和copy指针(此刻是浅拷贝// 还是指向的原来的对象,所以说不变。// 所以不可变对象的copy 和strong 与可变对象的copy 一样效果,赋值后copy 和 strong 指针指向的值都不变;/*1. 当原字符串是NSMutableString时,Strong属性只是增加了原字符串的引用计数,而Copy属性则是对原字符串做了次深拷贝,产生一个新的对象,且Copy属性对象指向这个新的对象,且这个Copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。2. 这里还有一个性能问题,即在原字符串是NSMutableString,Strong是单纯的增加对象的引用计数,而Copy操作是执行了一次深拷贝,所以性能上会有所差异(虽然不大)。如果原字符串是NSString时,则没有这个问题。所以,在声明NSString属性时,到底是选择strong还是copy,可以根据实际情况来定。不过,一般我们将对象声明为NSString时,都不希望它改变,所以大多数情况下,我们建议用copy,以免因可变字符串的修改导致的一些非预期问题。*/
}
- (void)test22{//NSMutableString *string = [NSMutableString stringWithFormat:@"测试文字"];self.strongStr = string;self.copyssStr = string;NSLog(@"String:%@   strongStr:%@   copyssStr:%@",string,self.strongStr,self.copyssStr);NSLog(@"String 地址: %p, %p", string, &string);NSLog(@"Strong 地址: %p, %p",_strongStr, &_strongStr);NSLog(@"Copy   地址: %p, %p",_copyssStr, &_copyssStr);NSLog(@"\n");[string appendString:@"我变了,你没变"];NSLog(@"append 后 String:%@   strongStr:%@   copyssStr:%@",string,self.strongStr,self.copyssStr);NSLog(@"append 后 String 地址: %p, %p", string, &string);NSLog(@"append 后 Strong 地址: %p, %p",_strongStr, &_strongStr);NSLog(@"append 后 Copy   地址: %p, %p",_copyssStr, &_copyssStr);NSLog(@"\n");// NSMutableString总结:// 如果string 的指针不变,内存地址不变,值变化,则strongStr 的值跟着变化,指针不变,地址不变;而copyssStr 则不会任何变化;string = [NSMutableString stringWithFormat:@"ccvcc"];NSLog(@"Mutable 后 String:%@   strongStr:%@   copyssStr:%@",string,self.strongStr,self.copyssStr);NSLog(@"Mutable 后 String 地址: %p, %p", string, &string);NSLog(@"Mutable 后 Strong 地址: %p, %p",_strongStr, &_strongStr);NSLog(@"Mutable 后 Copy   地址: %p, %p",_copyssStr, &_copyssStr);// 总结:Mutable 相当于重新alloc一个对象, string 指针的指向变了,指向了新的对象的地址,strongStr 指针不变,指向的还是原来对象的地址,地址不变;而copyssStr已经去string没有关系,则不会任何变化;// 这里我想验证下strongStr 指向的是原来的还是新的对象的[self performSelector:@selector(shows) withObject:nil afterDelay:10];
}
- (void)shows {NSLog(@"shows 后 strongStr:%@   copyssStr:%@",self.strongStr,self.copyssStr);
}

上面代码中有自己对比得出的结论,推出多用copy 是因为我们使用属性一般是全局的,不期望 *string被改变时,也改变了copy 属性的值。我们希望的是self.copyssStr = @"";来改变

参考:https://www.jianshu.com/p/8bbe01e53114

:https://blog.csdn.net/itianyi/article/details/9018567

:https://blog.csdn.net/summer_csdn123/article/details/52190879

:https://www.jianshu.com/p/b3873ac9259b

这篇关于(0087)iOS开发之NSString属性为什么要用copy来修饰?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/450782

相关文章

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

MySQL 事务的概念及ACID属性和使用详解

《MySQL事务的概念及ACID属性和使用详解》MySQL通过多线程实现存储工作,因此在并发访问场景中,事务确保了数据操作的一致性和可靠性,下面通过本文给大家介绍MySQL事务的概念及ACID属性和... 目录一、什么是事务二、事务的属性及使用2.1 事务的 ACID 属性2.2 为什么存在事务2.3 事务