NSString的Copy与内存分配

工业机器人关节拆装流程_一文读懂模块化直驱电机及机器人关节模组 私信“干货”二字,即可领取138G伺服与机器人专属及电控资料!如果说芯片是智能行业最为重要的核心元件,那么电机几乎可以说是支撑了整个自动化和大工业生产以及现代社会最为重要的部件,全世界90%的能源是由电机发出来的,而70%是由电机消耗调的,电机可以说是整个人类社会能源循环的占有绝对地位的产品。普通伺服电机伺服电机其实已经算是电动机中比较高端的类型,特别是永磁同步类型的伺服电机,由于其启动快速,惯量... 阅读详情

原文链接:http://tutuge.me/2015/02/18/NSString%E7%9A%84Copy%E4%B8%8E%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D/

前言

不管是用什么语言开发,字符串应该算是用的最多的了。在Objective-C中,字符串类是NSString,以及其子类NSMutableString等。所以,对于字符串类,编程语言、编译器等往往会做特殊处理。下面我就说说我自己在项目中发现的NSString的“奇怪”的地方。

字符串常量,copy,mutableCopy

Example

先看看如下面的代码,猜猜会输出什么:

NSString *str1 = @"abc";
NSString *str2 = @"abc";
NSString *str3 = [[NSString alloc] initWithString:@"abc"];
NSString *str4 = [str1 copy];
NSString *str5 = [str1 mutableCopy];

//输出内存中的地址
NSLog(@"str1: %p", str1);
NSLog(@"str2: %p", str2);
NSLog(@"str3: %p", str3);
NSLog(@"str4: %p", str4);
NSLog(@"str5: %p", str5);

直接给出结果:

//地址值由运行时决定,不唯一
str1: 0x10cd12040
str2: 0x10cd12040
str3: 0x10cd12040
str4: 0x10cd12040
str5: 0x7f874b508350 //mutable copy

看,是不是很“神奇”。

简单解释

NSString是“不可变(immutable)”的类型,这个是关键。
代码中的“@”开头的字符串,其实就是一个字符串常量,运行时会检测这个字符串是否已经存在,存在的话,就直接将这个字符串的地址赋给变量;不存在的话,则创建,再赋值。

第一行: “abc”字符串不存在,创建,取得字符串地址“0x10cd12040”,赋给str1.

第二行: “abc”字符串已经存在,直接将地址“0x10cd12040”赋给str2.

第三行: (记住,NSString是不可变的)alloc并不会分配新的内存,直接将字符串地址“0x10cd12040”赋给str3.

第四行: copy,既然是不可变的,也就没有必要分配新内存,直接将地址“0x10cd12040”赋给str4.

第五行: mutableCopy其实就是创建一个NSMutableString的实例,既然是“可变(mutable)”的类型了,当然要分配新的内存,所以,字符串的地址也变成新的“0x7f874b508350”。

可以这么说,编译器、runtime充分利用了NSString是“不可变(immutable)”类型这个特点,只要字符串内容一致,就不会分配新的内存储存,字符串在程序中使用量非常大,这么做无疑可以大大节省内存,提升性能。

Property 和 NSString

先来看看一个UserEntity类:

//UserEntity.h

@interface UserEntity : NSObject <NSCopying>
@property(strong, nonatomic) NSString *name;
@end

只有一个名为name的NSString类型Property。
相信大家对这个不陌生吧。一般我们的应用中会有很多Entity类型,每个Entity类里面肯定避免不了有许多NSString的字符串类型。这里的name的属性是:strong和nonatomic,strong表明name要“持有”一份name所指的字符串的引用,nonatomic表示property类型不用加锁。

接着咱们看看下面的代码:

UserEntity *userEntity = [UserEntity new];        

//创建mutable类型的字符串
NSMutableString *showName = [[NSMutableString alloc] initWithString:@"tutuge"];        

//先保存“tutuge”字符串到userEntity的name
userEntity.name = showName;        

//修改showName
[showName appendString:@" blog"];        

//输出userEntity的name属性
NSLog(@"Name: %@", userEntity.name);

猜猜会输出什么?

Name: tutuge blog

看,我们明明是保存的“tutuge”,怎么到后面输出的是“tutuge blog”?

让NSString类型的Property为Copy型

因为name的Property属性是strong的,所以赋值后,它跟showName均指向同一个NSMutableString实例,如下:

imageimage

所以改变了showName,当然name输出的值也就变了。
这个时候,name的property属性就不能是strong了,应该是copy,如下:

//UserEntity.h

@interface UserEntity : NSObject <NSCopying>
@property(copy, nonatomic) NSString *name;
@end

这样的话,当“userEntity.name = showName;”这句运行后,内存布局如下:

imageimage

这样,就避免了这个问题。

总结

很所时候,代码并不是看上去那样“运行”的,多试试,多查阅资料,就能了解其中的奥秘了~

告别 Python!C# 直接跑 YOLO 目标检测:工控机边缘推理终极方案 set;set;set;set;set;stringget;set;get;set;get;set;get;set;get;set;告别 Python 依赖,不是排斥 Python 的训练能力,而是为了工程化的极致。在工控机这个资源受限、稳定性要求极高的战场上,是目前最优雅、最高效的解决方案。更少的依赖= 更少的故障点。更快的速度= 更高的产线节拍。更简单的部署= 更低的人力成本。现在,拿起你的 C# 项目,导入那个.onnx。 阅读详情

相关推荐

2024高校网络安全管理运维赛题目--复现+题目+wp

官方writeup集思广益比较好的备份。

书山有路勤为径,学海无涯苦作舟 1319

NSString + Copy

拷贝 目的: 产生一个副本对象 比如桌面上有一个文件夹iOS,iOS文件夹中有一个名字叫做 iOS底层笔记二.docx的文件 . command + C, command + V . 会有一个 iOS底层笔记二的副本.docx 的文件。 这两个文件,我可以任意改变其中的一个文件,另一个文件不会受到影响。 特点:跟原对象互不影响 修改原对象,不会影响副本对象 修改副本对象,...

M316625387的博客 574

玩转ubuntu18 --机器视觉方面(yolo算法识别及摄像头和cmake问题解决)

玩转ubuntu18 --机器视觉方面(yolo v3算法识别) 1.YOLO的简介 工作原理 先前的检测系统重新调整分类器或本地化器以执行检测。他们将模型应用于多个位置和比例尺的图像。图像的高分区域被视为检测。 我们使用完全不同的方法。我们将单个神经网络应用于整个图像。该网络将图像划分为区域,并预测每个区域的边界框和概率。这些边界框按预测概率加权。 我们的模型比基于分类器的系统具有几个优势。它在测试时间查看整个图像,因此其预测由图像中的全球上下文提供信息。它还通过单一网络评估进行预测,这与R-CNN等系统

qq_53951823的博客 1556

NSString属性为什么要用copy

关于NSString作为属性的时候为什么要用copy,而非strong: 1、首先copy 分为深拷贝和浅拷贝,深拷贝是拷贝内容并存放到另一份内存空间,浅拷贝是指针拷贝,会随着内存中对象值的变化而变化; 2、NSString copy 浅拷贝 得到NSString NSMutableString copy 深拷贝 得到NSString NSString mutableCopy 深拷贝 得到NSMutableString NSMutableSt

qq_32940999的博客 2815

高等数学第五章---定积分(§5.3定积分的计算方法)

这篇博客详细讲解定积分的计算方法,包括直接法、凑微分法、变量代换法和分部积分法。通过典型例题演示如何运用这些技巧计算定积分,特别强调换元必换限的原则和奇偶函数的简化处理。内容涵盖代数变形、三角代换、分段函数积分等常见题型,并附有详细的解题步骤和常见错误分析。适合微积分学习者系统掌握定积分计算技巧,提升解题效率。文中还包含积分等式证明和变限积分函数求导等进阶内容,帮助读者深入理解定积分的应用。

2302_77045867的博客 4328

Python爬虫实战:5分钟搞定东方财富网股票数据抓取(附完整代码)

本文详细介绍了如何使用Python爬虫快速抓取东方财富网的股票数据,包括环境配置、API分析、核心代码实现及优化技巧。通过简单的requests和pandas库,5分钟内即可获取高质量股票数据,适合量化交易和数据分析初学者。

weixin_29040367的博客 1182

NSString的内存管理

NSString引用计数很特殊 大多数情况下string的retainCount都是无限大的数。这是因为,字符串创建出来不是在堆上的,而是在常量区。常量区只要值相同,就是同一块内存。常量区的值在APP结束时才会释放,指向这块内存的指针不受引用计数限制。 下面有三种情况: 情况一: NSString *Str1 = [NSStringstringWithFormat:@"a%d",11]

MM_dou的专栏 489

S32K144-EB tresos GPT驱动模块配置详解

GPT通用计时器,在S32K144这款芯片上,有4个外设模块,最多38各通道可以作为GTP的计时器通道,具体详细的大家可以去看芯片手册。这里咱们只管怎么用EB来配置GPT驱动。

小胡同学的工程师学习之路 3863

[IOS 开发] NSString内存管理,NSString放在内存的什么区域

测试代码: NSString *str1 = [NSString stringWithFormat:@"小强"]; NSString *str2 = [NSString stringWithFormat:@"1"]; NSString *str3 = [NSString stringWithFormat:@"a"]; NSString *str4 = @"123456789"; 上面这段代...

u010130947的专栏 2657

24、流化催化裂化的分子建模

本文探讨了流化催化裂化(FCC)的分子建模方法,重点分析了如何通过机理建模和模型修剪策略(如反应规则和随机规则)来减少计算复杂度,同时保持化学意义。文章还介绍了定量结构反应性关联(QSRC)在动力学参数确定中的应用,以及结焦对催化剂活性的影响。通过这些方法,FCC反应模型能够在预测产物分布的同时,显著提高计算效率。

s8t9u0v1w的博客 140

基于YOLO26深度学习框架的人脸识别门禁系统的算法研究实现方法

本文研究了基于YOLO26深度学习框架的人脸识别门禁系统实现方法。系统采用YOLO26目标检测算法,通过CSPDarknet53主干网络、特征金字塔结构和注意力机制实现高效人脸检测。研究内容包括数据预处理、模型训练优化和身份验证等关键技术,使用迁移学习策略和CIoU损失函数提升检测精度。该系统可应用于智能安防场景,具有实时性强、识别准确的特点,为门禁管理提供了智能化解决方案。

一键难忘的博客 766

NSString的内存管理之 __NSCFConstantString、NSTaggedPointerString、__NSCFString

&gt; 转自:http://skyfly.xyz/2015/11/08/iOS/NSString%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/  by skyfly   在 Objective-C 的 Fondation 框架中 NSString 对象是很复杂的存在,各种方式创建以及不同长度的字符串都会影响 NSString 对象在内存中所处的...

王学森的专栏 6885

Zephyr内核——内存管理——内存堆

Zephyr提供了一组允许线程动态分配内存。

wayne2018的博客-心情驿站 771

NSString用copy和strong的区别

NSString为不可变字符串,用copy和strong都是只分配一次内存。 1、但是如果用copy,需要先判断字符串是不是不可变字符串,如果是不可变字符串,就不在分配空间,如果是可变字符串才分配空间。 2、如果程序中用到NSString比较多,每次都先判断会耗费性能,用strong则不会再判断了,所以不可变字符串可以直接用strong修饰。 ...

qq_32117417的博客 568

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

字符串的copy和strong,数组的copy

字符串的copy和strong,数组的copy

u013712343的博客 1150

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

NSString对象和普通对象的区别

首先,从内存管理层面看: 普通对象都是存储到堆内存上,而对于NSString对象: NSString 初始化方法的内存方式比较 NSString*str1 =@"hello"; NSString*str2 =@"hello"; NSString*str3 = [NSStringstringWithFormat:@"hello"]; NSStr...

erge的博客 326

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

copy 和 mutableCopy

对于可变的对象(NSMutableString)   使用copy 和 mutableCopy 会产生新的指针和新的对象(新的指针指向新的对象)  而且 改变原件 不会改变副本  改变副本 不会改变原件(说明原来的一个指针和新生成的两个指针 指向不同的内存地址 会产生新的对象); 对于不可变的对象(NSString)   使用 mutableCopy 会产生新

Coder 278

iOS深拷贝与浅拷贝、NSString内存分配

copy与retain的区别: 1)copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。 2)retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容...

weixin_34054866的博客 179

[iOS]-NSString的三种管理方式

[iOS]-NSString的三种管理方式浅谈

m0_52192682的博客 432

copy和mutableCopy,retain

1 copy与retain的区别copy: copy是创建一个新对象(又称为内容拷贝或深拷贝); copy时两个对象内容相同,地址不同。 新的对象引用计数为1,与旧有对象的引用计数无关。 copy减少对象对上下文的依赖。 retatin: retain是创建一个指针(又称为指针拷贝或浅拷贝) retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容相同。 retain对象的引用计数加1,

童真的烂漫的专栏 498

ARC & MRC下string内存管理策略探究

前两天跟同事争论一个关于NSString执行copy操作以后是否会发生变化,两个人整了半天,最后写代码验证了一下,发现原来NSString操作没我们想的那么简单,下面就让我们一起看看NSString和NSMutableString在MRC下执行retain,copy,mutableCopy,以及ARC下不同的修饰__weak, __strong修饰赋值究竟发生了什么。   一、验证代码如下:

hanmingsa的专栏 640

理解 retain 、copy 、NSMutableString 、NSString 的用法

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34090562的博客 120

retain与copy的区别

retain是指针拷贝, copy是内容拷贝。 retain:释放旧对象,将旧对象的值赋予输入对象,再将输入对象的引用计数值+1。 copy:建立一个引用计数为1的对象,然后释放旧对象。 比如一个NSString对象,地址为0×1111,内容为@”STR” Copy到另外一个NSString之 后,地址为0×2222,内容相同,新的对象retain为1, 旧有对象没有变化 ret

罗先生的技术博客 509

assign、retain、copy的区别

这是在网上找的一篇,解释三者区别最清楚的。 ================================== 举个例子可能更好理解点  NSString *pt = [[NSString alloc] initWithString:@"abc"];  上面一段代码会执行以下两个动作  1 在堆上分配一段内存用来存储@"abc"  比如:内存地址为:0X1111 内容为 "abc" 

萱的house 976

iOS: ARC & MRC下string内存管理策略探究

ARC & MRC下string内存管理策略探究      前两天跟同事争论一个关于NSString执行copy操作以后是否会发生变化,两个人整了半天,最后写代码验证了一下,发现原来NSString操作没我们想的那么简单,下面就让我们一起看看NSString和NSMutableString在MRC下执行retain,copy,mutableCopy,以及ARC下不同的修饰__weak...

weixin_30265171的博客 88

探讨NSString和NSMutableString的内存问题以及copy和MutableCopy两个方法

NSString: 1 //main.m 2 #import <Foundation/Foundation.h> 3 4 int main(int argc, const char * argv[]) { 5 @autoreleasepool { 6 7 NSString *str1 = @"aaa...

weixin_30668887的博客 72
上一篇: Effective-Objective-C-读书笔记-Item-3
下一篇: UITableView优化
github_26452845
博客等级 码龄12年 1粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值