三种字符串的管理方式

NSString的三种实现方式

OC这个语言在不停的升级自己的内存管理,尽量的让自己的

OC的字符串

问题引入

在学习字符串的过程中间会遇到一个因为OC语言更新造成的问题

例如:

int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = [NSString stringWithFormat:@"hello"];NSString* str2 = [NSString stringWithFormat:@"hello"];NSString* str3 = @"hello";NSLog(@"%d", str1 == str2);NSLog(@"%d", str2 == str3);}return 0;
}

按照书上的老版本来说的话,我们这里应该输出两个0才对,因为一个第一个和第二个都是堆区创建的他们应该是不一样的,但是结果却出乎我们的意料,我们这里在堆区中创建的两个字符串的指针地址是一样的。结果输出了1。下面我们就解决一下这个问题。

在这里插入图片描述

我们这时候输出一下这几个字符串的类型,这里就出现了这个NSTaggedPointerString这个类型,这时候我们会感到困惑,为什么我们明明是一个NSString类型,但是为什么会有这几种情况呢?这里涉及到一个类簇的问题,但是这里就简单理解成我们在这个NSString这个大类下有三种小的类别来管理这个类型,从而让字符串有一个更好的储存方式来保障我们的内存使用。

在这里插入图片描述

这时候,我们来正式介绍一下在OC中间有关字符串的几种实现方式。

OC中字符串NSString有三种实现方式,分别为

__NSCFConstantString,

__NSCFString,

NSTaggedPointerString.

现在我们通过一段代码来分析这三种字符串的差异

代码示例

我们给出一段代码来分析一下有关这三种字符串的内容:

int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = @"hello";NSString* str2 = [NSString stringWithFormat:@"helloworld"];NSString* str3 = [NSString stringWithFormat:@"神"];NSString* str4 = [NSString stringWithFormat:@"hello"];NSLog(@"%lu, %@", [str1 retainCount], [str1 class]);NSLog(@"%lu, %@", [str2 retainCount], [str2 class]);NSLog(@"%lu, %@", [str3 retainCount], [str3 class]);NSLog(@"%lu, %@", [str4 retainCount], [str4 class]);//输出他的一个引用计数和一个类型}return 0;
}

这是这个的输出结果:

在这里插入图片描述

我们现在就了解一下这三种字符串

__NSCFConstantString类型
  • 这个字符串类型是在常量区创建的一个字符串
  • 这个字符串是一种编译时的常量
  • 我们可以用@""stringWithString方式创建
  • 打印的retainCount的值是很大的,无法通过release方式去释放,是一个单例模式
int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = @"hello";NSString* str2 = [NSString stringWithFormat:@"helloworld"];NSString* str3 = [NSString stringWithFormat:@"神"];NSString* str4 = [NSString stringWithFormat:@"hello"];NSLog(@"%lu, %@", [str1 retainCount], [str1 class]);//NSLog(@"%lu, %@", [str2 retainCount], [str2 class]);//NSLog(@"%lu, %@", [str3 retainCount], [str3 class]);//NSLog(@"%lu, %@", [str4 retainCount], [str4 class]);[str1 release];NSLog(@"%lu, %@", [str1 retainCount], [str1 class]);}return 0;
}

这里我们进行了一次release操作,按道理来说我们应该是把对他进行了一次释放的,但是打印结果是

在这里插入图片描述

这里发现我们无法对其进行释放,所以我们可以认为他是一个单例。

__NSCFString

  • 这个字符串类型是一个在堆区创建的一个字符串
  • 这个字符串是在运行的时候创建的
  • 较长字符串会自动转化成这个类型
  • 中文字符串也会自动转成这个类型
    这是他的引用计数:
    在这里插入图片描述

从引用计数可以看出他不是一个单例,可以被释放。
借用一段学长的话来对于这个字符串类型进行一个讲解:

即使两个对象的内容相同,它们在堆上的内存地址也是不同的。每个对象都在独立的内存空间中存储,具有自己的地址。这意味着通过不同的对象引用访问这两个对象时,实际上访问的是不同的内存地址。

NSTaggerPointerSring

这个字符串类型是最新的一个字符串类型,他也是在堆区创建的但是他可用用来存储一下较短字符串,实现一个节约内存的效果,引用一段学长的话

TaggedPointer的意思是标签指针,这是苹果在 64 位环境下对 NSString,NSNumber
等对象做的一些优化。简单来讲可以理解为把指针指向的内容直接放在了指针变量的内存地址中,因为在 64 位环境下指针变量的大小达到了 8
位足以容纳一些长度较小的内容。于是使用了标签指针这种方式来优化数据的存储方式。从他的引用计数可以看出,这货也是一个释放不掉的单例常量对象。在运行时根据实际情况创建。

这里是有关他的引用计数:
在这里插入图片描述
从这里可以看出他是一个单例。
也是通过一个stringWithFormat方式,但是由于较短英文字符串,所以可以用地址来直接存储较短英文字符串的数值,这是一个单例。

  • 是一个单例
  • 是在堆区创建的一个字符串
  • 可以将其当作一个伪对象,对象直接被存储在指针的地址上面
  • 较短且在堆区创建的字符串会呈现出这个样式(长度小于9)

总结

我们这里简单介绍了三种字符串的实现方式,这里只是简单的介绍了这三种字符串的格子的一个特点,没有深入的去研究它的底层代码,我们这里主要需要理解在不同的情况下,字符串的创建出的类别是不一样的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/20997.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++核心编程类的总结封装案例

C类的总结封装案例 文章目录 C类的总结封装案例1.立方体类的封装2.点与圆的关系的封装3.总结 1.立方体类的封装 在C中,我们可以定义一个立方体(Cube)类来封装立方体的属性和方法。立方体的属性可能包括边长(side length&#xff…

【redis】set和zset常用命令

set 无序集合类型 sadd 和 smembers SADD:将一个或者多个元素添加到set中。注意,重复的元素无法添加到set中。 语法:SADD key member [member] 把集合中的元素,叫做member,就像hash类型中,叫做field类似. 返回值表示本次操作,添加成功了几个元素. 时间复…

网络原理——http/https ---http(1)

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 网络原理 HTTP/HTTPS HTTP,全称为"超文本传输协议" HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议. 实际上,HTTP最新已经发展到 3.0 但是当前行业中主要使用的HT…

概念解析 | 为什么SAR中的天线间隔需要是四分之一波长?

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:为什么SAR中的天线间隔需要是四分之一波长 概念解析 | 为什么SAR中的天线间隔需要是四分之一波长? 在这篇文章中,我们将深入探讨**合成孔径雷达(SAR)**系统中,为什么天…

明日周刊-第12期

以前小时候最期待六一儿童节了,父母总会给你满足一个愿望,也许是一件礼物也许是一次陪伴。然而这个世界上其实还有很多儿童过不上儿童节,比如某些地区的小孩子,他们更担心的是能不能见到明天的太阳。 文章目录 一周热点航天探索火…

LeetCode-77. 组合【回溯】

LeetCode-77. 组合【回溯】 题目描述:解题思路一:回溯背诵版解题思路三:0 题目描述: 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入&a…

Python怎么使用 SQLAlchemy 和model 查询数据呢?

SQLAlchemy是一个流行的Python SQL工具包和对象关系映射器(ORM)。 假设正在使用 SQLAlchemy 并有一个模型 MyModel,使用这个模型以及 query 方法来查询数据库。 这里有一个基本的例子,说明如何使用 SQLAlchemy 的 query 方法和 wi…

算法-对列表元素划分成两个和值最大且相等的子列表

现有私募基金发行一支特殊基金产品,该基金认购人数上限不超过 30 人, 募集总金额不超过 3000W,每个投资人认购金额不定。该基金只能将募集到的钱用于投资两支股票,且要求两支股票投资金额必须相同,且每位投资人的钱只能…

0X JavaSE-- 集合框架【Collection(List、Set、Queue)、Map】

每一个集合类底层采用的数据结构不同,例如ArrayList集合底层采用了数组,LinkedList集合底层采用了双向链表,HashMap集合底层采用了哈希表,TreeMap集合底层采用了红黑树。**集合中存储的是引用。**即。集合中存放的是对象的地址&am…

springboot报错:Failed to start bean ‘documentationPluginsBootstrapper‘

项目场景: springboot项目启动时报错 问题描述 具体报错信息: 可能原因分析: 1、SpringFox的版本与Spring Boot的版本不兼容。解决这个问题,你可能需要检查你正在使用的SpringFox和Spring Boot的版本,确保它们是兼容…

一千题,No.0037(组个最小数)

给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最…

[AIGC] 使用Flink SQL统计用户年龄和兴趣爱好

Apache Flink是一个具有强大计算能力、高吞吐量、低延迟的分布式计算框架,它支持批计算和流计算。Flink SQL是Flink ecosystem的一部分,是一种对结构化数据进行批和流处理的声明式语言。本文以一个简单的实例讲解如何使用Flink SQL来统计用户年龄和兴趣爱…

C# 面向对象编程(一)——类 第三篇

总目录 C# 语法总目录 系列链接 C# 面向对象编程(一) 类 第一篇 C# 面向对象编程(一) 类 第二篇 C# 面向对象编程(一) 类 第三篇 C# 面向对象编程 一 ——类 第三篇 简介面向对象编程类 第三篇9. 重载运算符10. 分部方法** nameof方法 **** GetType 方法和 typeof方…

【Intro】Heterogeneous Graph Attention Network(HAN)

论文链接:https://arxiv.org/pdf/1903.07293 Abstract 异构性和丰富的语义信息给面向异构图的图形神经网络设计带来了巨大的挑战。 -> 一种基于分层注意的异构图神经网络,包括节点级注意和语义级注意。具体来说,节点级关注旨在学习节点…

GPT4o还没用上?落后一个月!

文章目录 一.Share官方网站:以一半的价格享受官网服务1.1 网址1.2 一些介绍和教学实战:1.3 主界面(支持4o):1.4 GPTS(上千个工具箱任你选择):1.5 快速的文件数据分析(以数学建模为例…

一次“yarn Couldn‘t find package“问题的排查

本文记录一次使用yarn install 时报错 Couldn’t find package xxxx 问题的排查。 问题描述 问题来自于笔者对一个前端项目进行debug时的yarn install 报错信息,在一个可以明确代码没有问题的项目中,因为切换环境,重新执行yarn install,发现…

qt qcomboBox实现自动检索功能 通过输入匹配字符进行筛选

本人做了一个自定义控件SeepedSearch 用于快速检索匹配的字符的下拉框 方便查找目标 直接上源码 1. SpeedSerach.h #pragma once #include class QComboBox; class QCompleter; class SpeedSearch : public QWidget { Q_OBJECT public: explicit SpeedSearch(QWidget *paren…

web前端三大主流框架指的是什么

web前端三大主流框架是什么?前端开发师的岗位职责有哪些?这边整理了相关内容供大家参考了解,请各位小伙伴随小编一起查阅下面的内容。 web前端三大主流框架 web前端三大主流框架是Angular、React、Vue。 1.Angular Angular原名angularJS诞生…

如何用python做一个贪吃蛇程序?——浔川AI社(VIP)

1 游戏说明: 死亡条件:碰壁、吃自己! 状态:只有吃了食物才会随机生成其中一种状态,分别是:稳如老狗、幸运光滑、衰神附体之一 状态:稳如老狗:相对于上一次速度不变! 状态:幸运光滑:相对于上一次速度变慢! 状态:衰神附体:相对于上一次速度变快! 总体速率对比…

UnityAPI学习之Transform组件基本使用

目录 Transform组件 访问与获取 Transform的位置和旋转信息 Transform局部坐标和旋转信息的获取 Transform的缩放与正方向 缩放(Scale) 正方向 Transform相关的查找方法 销毁游戏物体 Transform组件 访问与获取 现在创建一个容器放置GrisGO物…