三种字符串的管理方式

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)

总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ZCU102启动镜像(详细版)

ZCU102启动镜像--详细版本 详细步骤1、安装好Vitis(GUI界面)、 Vivado、 Petalinux软件然后vivado这边的操作就先结束了 创建Petalinux工程编译镜像打包 详细步骤 B站参考视频链接: link 1、安装好Vitis(GUI界面)、 Vivado、 Pe…

SpringBoot:手动创建应用

Spring提供了在线的Spring Initialzr在线创建Spring Boot项目,为了更好的理解Spring Boot项目,这里我们选择手动创建。 1.新建Web应用 1.1 生成工程 首先要做是创建一个Java项目,这里我们选择使用Maven来支持,使用archetype:ge…

C++进阶之AVL树+模拟实现

目录 目录 一、AVL树的基本概念 1.1 基本概念 二、AVL树的模拟实现 2.1 AVL树节点的定义 2.2 插入操作 2.3 旋转操作 2.4 具体实现 一、AVL树的基本概念 1.1 基本概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树&…

【论文速读】Self-Rag框架,《Self-Rag: Self-reflective Retrieval augmented Generation》

关于前面的文章阅读《When to Retrieve: Teaching LLMs to Utilize Information Retrieval Effectively》,有网友问与Self-Rag有什么区别。 所以,大概看了一下Self-Rag这篇论文。 两篇文章的方法确实非常像,Self-Rag相对更加复杂一些。 When …

图数据库Neo4j——Neo4j简介、数据结构 Docker版本的部署安装 Cypher语句的入门

前言 MySQL是一种开源的关系型数据库管理系统,使用SQL作为其查询语言,常见的关系型数据库有MySQL、Oracle、SQL Server、PostgreSQL等。相关博客文章如下: 【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身PostgreSQL数…

计算机系统结构之流水

一、标量流水线的主要性能 吞吐率是流水线单位时间里能流出的任务数或结果数(最大吞吐率:单位时间内计算机所能处理的最多指令条数)。 流水线中经过时间最长的子过程成为瓶颈子过程。最大吞吐率取决于瓶颈段的时间。 实际吞吐率: 加速比: …

教你搞一个比较简单的计时和进度条装饰器 (多线程进阶版)

简单的计时和进度条装饰器 - 多线程进阶版 这个进阶版有什么?话不多说上代码效果图 上一篇关于装饰器的Blog 这个进阶版有什么? 在上一个装饰器工作时,跑了20秒后就停止了。如果运行的函数跑了60秒,后面的40秒我们是只能等到结束…

CAD二次开发(7)- 实现Ribbon选项卡,面板,功能按钮的添加

1. 创建工程 2. 需要引入的依赖 如图,去掉依赖复制到本地 3. 代码实现 RibbonTool.cs 实现添加Ribbon选项卡,添加面板,以及给面板添加下拉组合按钮。 using Autodesk.Windows; using System; using System.Collections.Generic; using S…

悬剑武器库5.04版

工具介绍 悬剑5 基于“悬剑网盘”精选工具集悬剑5“飞廉”云武器库制作。 操作系统:Windows 10 专业版 锁屏密码:secquan.org 解压密码: 圈子社区secquan.org 镜像大小:33.1GB 系统占用空间63.0 GB 镜像导入 下载镜像,文末…

WordPress博客主题触屏版社区源码

下载地址:WordPress博客主题触屏版社区源码

【Unity之FGUI】黑神章Fairy GUI控件详解

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:就业…

python采集汽车价格数据

python采集汽车价格数据 一、项目简介二、完整代码一、项目简介 本次数据采集的目标是车主之家汽车价格数据,采集的流程包括寻找数据接口、发送请求获取响应、解析数据和持久化存储,先来看一下数据情况,完整代码附后: 二、完整代码 #输入请求页面url #返回html文档 imp…

6.3 Go 结构体(Struct)

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

普华永道信任危机:上市公司解约风波与反思

在全球会计业界的星空中,普华永道无疑是那颗最为耀眼的星之一。然而,近日这颗星却遭遇了前所未有的信任危机。这家大名鼎鼎的四大会计师事务所之一,近期陷入了上市公司解约的风波之中,其声誉与地位正面临严峻挑战。 就在昨晚&…

Word2Vec模型的引入介绍与相关概念

一 、Word2Vec模型的背景引入 1.1 One-hot模型 One-hot模型是是用N位的状态寄存器对N个状态进行编码 如下所示,是有4个样本,每个样本都有三个特征,特征1表示当前样本的性别。 我们喂给算法怎么样的数据,算法就会给我们一个怎么…

学习笔记——IP地址网络协议——网络层(IP)协议

一、网络层(IP)协议 网络层(被称为IP层)但网络层协议并不只是IP协议,还包括ICMP(Internet Control Message Protocol)协议、IPX(Internet Packet Exchange)协议等。 1、IP协议 IP(Internet Protocol)本身是一个协议文件的名称,该协议文件的内容非常少&…

使用python统计word文档页数

使用python统计word文档页数 介绍效果代码 介绍 使用python统计word文档的页数 效果 代码 import os import comtypes.clientdef get_word_page_count(docx_path):try:# Initialize the COM objectword comtypes.client.CreateObject(Word.Application)word.Visible False…

【Qt】探索Qt绘图世界:自定义控件与视觉效果的全面指南

文章目录 前言:1. 绘图基本概念2. 绘制各种形状3. 绘制文字(显示文字)、设置画笔4. 画刷5. 绘制图片6. 特殊的绘图设备总结: 前言: 在软件开发中,图形用户界面(GUI)的设计是至关重要…

【面试题】CAP理论、BASE理论及其注册中心选型

1.CAP理论 CAP:指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性),三者不可同时获得 一致性(C&#x…

成功解决“IndexError: pop index out of range”错误的全面指南

成功解决“IndexError: pop index out of range”错误的全面指南 引言 在Python编程中,处理列表(list)、双端队列(deque)或其他可迭代对象时,我们经常使用pop()方法来移除并返回指定索引处的元素。然而&am…