NSString有哪些创建对象的方法?创建的对象分别存储在什么区域?

NSString有哪些创建对象的方法?创建的对象分别存储在什么区域?

一般通过NSString创建对象的方法有:

  1. NSString *string1 = @"123";
  2. NSString *string2 = [[NSString alloc] initWithString:@"123"];
  3. NSString *string3 = [NSString stringWithFormat:@"123"];
  4. NSString *string4 = [[NSString alloc] initWithFormat:@"123"];

这里面涉及到几个问题:
创建的对象存储在什么区?常量区?堆区?还是小对象?

因此,我们做打印,看结果分析:

//目的:看看字符串长度短的情况下
NSString *string0 = @"sun";//常量区
//目的:看看字符串长度很长的情况下
NSString *string1 = @"sundaopjd2221";//常量区NSString *string2 = [[NSString alloc] init];//常量区
NSString *string3 = [[NSString alloc] initWithString:@"sun"];//常量区
//目的:看看字符串长度短的情况下,下一个存储空间地址是啥
NSString *string4 = [[NSString alloc] initWithString:@"sun2"];//常量区
//目的:看看字符串长度很长的情况下,有没有变化
NSString *string5 = [[NSString alloc] initWithString:@"sundaopjd2221"];//常量区//目的:看看字符串长度短的情况下,存储空间地址
NSString *string6 = [NSString stringWithFormat:@"1"];//小对象
//目的:看看字符串长度短的情况下,下一个存储空间地址是啥
NSString *string7 = [NSString stringWithFormat:@"2"];//小对象
//目的:看看字符串长度很长的情况下,有没有变化
NSString *string8 = [NSString stringWithFormat:@"sundaopjd2221"];//存储在堆
//目的:观察堆空间的变化
NSString *string9 = [NSString stringWithFormat:@"sundaopjd222122"];//存储在堆//目的:看看字符串长度短的情况下,存储空间地址
NSString *string10 = [[NSString alloc] initWithFormat:@"1"];//小对象
//目的:看看字符串长度短的情况下,下一个存储空间地址是啥
NSString *string11 = [[NSString alloc] initWithFormat:@"3"];//小对象
//目的:看看字符串长度很长的情况下,有没有变化
NSString *string12 = [[NSString alloc] initWithFormat:@"sundaopjd2221"];//存储在堆
//目的:观察堆空间的变化
NSString *string13 = [[NSString alloc] initWithFormat:@"sundaopjd2221222"];//存储在堆//这个是指针本身的存储地址(栈)
NSLog(@"%p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p", &string0, &string1, &string2, &string3, &string4, &string5, &string6, &string7, &string8, &string9, &string10, &string11, &string12, &string13);//看看string的类型
NSLog(@"%@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@, %@", [string0 class], [string1 class], [string2 class], [string3 class], [string4 class], [string5 class], [string6 class], [string7 class], [string8 class], [string9 class], [string10 class], [string11 class], [string12 class], [string13 class]);//这个是对象存储的地址
NSLog(@"%p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p", string0, string1, string2, string3, string4, string5, string6, string7, string8, string9, string10, string11, string12, string13);//看看引用计数器个数
NSLog(@"%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", [string0 retainCount], [string1 retainCount], [string2 retainCount], [string3 retainCount], [string4 retainCount], [string5 retainCount], [string6 retainCount], [string7 retainCount], [string8 retainCount], [string9 retainCount], [string10 retainCount], [string11 retainCount], [string12 retainCount], [string13 retainCount]);打印结果:
0x7ff7bfeff290, 0x7ff7bfeff288, 0x7ff7bfeff280, 0x7ff7bfeff278, 0x7ff7bfeff270, 0x7ff7bfeff268, 0x7ff7bfeff260, 0x7ff7bfeff258, 0x7ff7bfeff250, 0x7ff7bfeff248, 0x7ff7bfeff240, 0x7ff7bfeff238, 0x7ff7bfeff230, 0x7ff7bfeff228__NSCFConstantString, __NSCFConstantString, __NSCFConstantString, __NSCFConstantString, __NSCFConstantString, __NSCFConstantString, NSTaggedPointerString, NSTaggedPointerString, __NSCFString, __NSCFString, NSTaggedPointerString, NSTaggedPointerString, __NSCFString, __NSCFString//混淆关闭前
//0x100004038, 0x100004058, 0x7ff846c7c2d0, 0x100004038, 0x100004078, 0x100004058, 0x9329a7a56318529b, 0x9329a7a56318519b, 0x600000207100, 0x600000c04ba0, 0x9329a7a56318529b, 0x9329a7a56318509b, 0x600000207120, 0x600000c04bd0
//混淆关闭后
0x100004038, 0x100004058, 0x7ff846c7c2d0, 0x100004038, 0x100004078, 0x100004058, 0x3115, 0x3215, 0x600000209340, 0x600000c0cba0, 0x3115, 0x3215, 0x3315, 0x600000c0cbd0-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1

分析:

通过打印[string class]获取的类型:__NSCFConstantString,NSTaggedPointerString,__NSCFString
可以知道创建的对象分别存储在什么区:常量区、小对象、堆区

通过打印[string retainCount]获取引用计数器:-1,1的结果,可以区分:
-1:常量区或小对象
1:堆区

问:为啥retainCount会为-1?

这是因为retainCount是一个无符号整型typedef unsigned long NSUInteger;
因此,-1并不代表是真正的引用计数器的值

在iOS中,遇到retainCount返回-1(或者在某些情况下是UINT_MAX,因为retainCount返回的是NSUInteger,一个无符号整型)通常是指对象被标记为不可释放或具有“无限”的引用计数。这种情况通常发生在几种特殊对象上,这些对象由于各种原因,被系统视为“永久存活”的,直到应用程序结束。这样的对象不参与常规的引用计数管理,也就是说,无论对它们进行多少次retainrelease操作,它们都不会被销毁。

这里的-1或UINT_MAX并不表示实际的引用计数值,而是一个标志,表明这个对象是由系统以特殊方式管理的。对于开发者来说,这意味着这类对象的内存管理并不需要(也不应该)手动干预。

几个典型的例子包括:

  • 单例对象:如[UIApplication sharedApplication][NSFileManager defaultManager],这些单例在应用程序的整个生命周期内都应该保持活跃状态。
  • 字符串字面量:如NSString *str = @"constant string";,这些字符串在编译时被创建,并存储在应用程序的二进制文件中。它们在整个应用程序的生命周期内都是有效的,因此被认为是具有“无限”引用计数的。
  • 标准框架对象:某些由系统框架创建并管理的对象,可能也会被标记为具有“无限”引用计数。

结论:

  • 通过NSString *str = @"1"[NSString alloc] initWithString:@"1"]创建的对象一致,都是存储在常量区

虽然有initWithString,有init,但也是放在常量区,不增加引用计数器

  • 通过[NSString stringWithFormat:@"2"];[[NSString alloc] initWithFormat:@"2"];创建的对象一致,当字符串长度小的时候(小于10)都是小对象,字符串长度过长的时候(大于等于10)存储在堆区域
//9个数
NSString *string11 = [[NSString alloc] initWithFormat:@"123456789"];
//10个数
NSString *string12 = [[NSString alloc] initWithFormat:@"1234567890"];
打印类型结果:
NSTaggedPointerString, __NSCFString
  • 小对象的引用,与小对象本身的地址不一致,即NSString *string6 = [NSString stringWithFormat:@"1"]; string6的地址,与[NSString stringWithFormat:@"1"];的地址不一致。
    因为string6是在栈上的,然后string6内部有一部分特定区域,存放小对象"1"

猜测:小对象存储在栈区

在这里插入图片描述

在这里插入图片描述

在现在的版本中,为了保证数据安全,苹果对 Tagged Pointer 做了数据混淆,开发者通过打印指针无法判断它是不是一个Tagged Pointer,更无法读取Tagged Pointer的存储数据。
所以在分析Tagged Pointer之前,我们需要先关闭Tagged Pointer的数据混淆,以方便我们调试程序。通过设置环境变量OBJC_DISABLE_TAG_OBFUSCATION为YES。

iOS - 老生常谈内存管理(五):Tagged Pointer

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

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

相关文章

解决方案:如何安装neo4j软件

文章目录 一、安装JDK二、安装neo4j 一、安装JDK 第一步先安装JDK,因为neo4j环境需要JDK,过程比较多,截图如下: 安装JDK网址 https://www.oracle.com/java/technologies/downloads winR,输入cmd,再输入j…

Leetcode70. 爬楼梯(动态规划)

Leetcode原题 Leetcode70. 爬楼梯 标签 记忆化搜索 | 数学 | 动态规划 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?示例 1:输入:n 2 输出:2 解…

数据分析之POWER Piovt透视表分析与KPI设置

将几个数据表之间进行关联 生成数据透视表 超级透视表这里的字段包含子字段 这三个月份在前面的解决办法 1.选中这三个月份,鼠标可移动的时候移动到后面 2.在原数据进行修改 添加列获取月份,借助month的函数双击日期 选择月份这列----按列排序-----选择月…

C++ 控制语句(一)

一 顺序结构 程序的基本结构有三种: 顺序结构、分支结构、循环结构 大量的实际问题需要通过各种控制流程来解决。 1.1 顺序结构 1.2 简单语句和复合语句 二 循环 2.1 for循环 语句流程图 注意:使用for语句的灵活性 三 while语句 四 do while语句

【LLM多模态】Cogvlm图生文模型结构和训练流程

note Cogvlm的亮点: 当前主流的浅层对齐方法不佳在于视觉和语言信息之间缺乏深度融合,而cogvlm在attention和FFN layers引入一个可训练的视觉专家模块,将图像特征与文本特征分别处理,并在每一层中使用新的QKV矩阵和MLP层。通过引…

【LaTeX】7实现章节跳转

使用 LaTeX 实现章节跳转 写在最前面1. 引入 hyperref 包2. 标记章节3. 引用章节示例代码注意 小技巧总结 🌈你好呀!我是 是Yu欸 🌌 2024每日百字篆刻时光,感谢你的陪伴与支持 ~ 🚀 欢迎一起踏上探险之旅,…

Vue 3中ref和reactive的区别

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

碳课堂|什么是碳资产?企业如何进行碳资产管理?

碳资产是绿色资产的重要类别,在全球气候变化日益严峻的背景下备受关注。在“双碳”目标下,碳资产管理是企业层面实现碳减排目标和低碳转型的关键。 一、什么是碳资产? 碳资产是以碳减排为基础的资产,是企业为了积极应对气候变化&…

就业班 第二阶段 2401--3.25 day5 mycat读写分离

[TOC] 启动并更改临时密码 [rootmysql1~]# systemctl start mysqld && passwdgrep password /var/log/mysqld.log | awk END{ print $NF} && mysqladmin -p"$passwd" password Qwer123..; MyCAT读写分离 Mycat 是一个开源的数据库系统,但…

遇到了问题,Firepower 2140配置带外IP时报错 commit-buffer failed

onsite we have a cisco firepower 2140 device which run ASA as we try to modify the 2140 OOB mgmt ip by CLI, we got an error why ? 经过查询发现,需要进入ASA里面打上以下这条命令,并重启ASA 1 修改模式并重启 ciscoasa# configure termina…

idea使用git笔记

1.创建分支和切换分支 创建分支 切换分支 2.把新创建的分支提交到远程服务器上(注:如果没有提交的,随便找个文件修改再提交) (1)切换到要提交的分支,add (2)commit (3)push 3.在自己分支修改代码及提交到自己的远…

STM32收发HEX数据包

在实际应用中,STM32的串口通信都是以数据包格式进行收发,这个数据包一般都包含包头和包尾,表示一个数据包。源代码在文末给出 数据包格式: 固定长度,含包头包尾 可变包长,含包头包尾 问题1:当…

C语言例4-15:从键盘输入一个整数,求其绝对值并输出。

代码如下&#xff1a; //从键盘输入一个整数&#xff0c;求其绝对值并输出。 #include<stdio.h> int main(void) {int n;printf("输出一个整数&#xff1a; \n");scanf("%d",&n); //从键盘输入一个整数保存至变量nif(n<0) //…

C#打印50*30条码标签

示例图&#xff1a; 源码下载地址&#xff1a;https://download.csdn.net/download/tiegenZ/89035407?spm1001.2014.3001.5503

混合云构建-使用 Azure ExpressRoute 建立从本地到 Azure 虚拟网络的专用连接

如果有大量业务数据需要在本地数据中心和azure私有网络进行传输&#xff0c;同时保证带宽和时延的情况需要使用 ExpressRoute 设置从本地网络到 Azure 中的虚拟网络的专用连接。以下是实操步骤供参考&#xff1a; 一、创建和预配 ExpressRoute 线路 登录 Azure 门户。 在页面顶…

comfyui 代码结构分析

comfyui的服务器端是用aiohtttp写的&#xff0c;webui是fastapi直接构建的&#xff0c;但是其实comfyui的这种设计思路是很好的&#xff0c;也许我们不需要在后端起一个复杂的前台&#xff0c;但是可以借助json结构化pipeline&#xff0c;然后利用node节点流把整个流程重新映射…

DaisyDisk for mac 苹果电脑磁盘清理工具

DaisyDisk for Mac是一款直观易用的磁盘空间分析工具&#xff0c;专为Mac用户设计&#xff0c;旨在帮助他们快速识别和管理磁盘上的文件与文件夹&#xff0c;从而释放存储空间。 软件下载&#xff1a;DaisyDisk for mac 激活版 DaisyDisk采用独特的可视化界面&#xff0c;将磁盘…

2024年目前阿里云服务器一个月收费价格表多少钱?

阿里云服务器一个月多少钱&#xff1f;最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年&#xff0c;折合5元一个月&#xff0c;2核4G服务器30元3个月&#xff0c;2核2G3M带宽服务器99元12个月&#xff0c;轻量应用服务器2核4G4M带宽165元12个月&#xff0c;4核16G服务…

基于OneAPI+ChatGLM3-6B+FastGPT搭建LLM大语言模型知识库问答系统

搭建大语言模型知识库问答系统 部署OneAPI部署一个LLM模型部署嵌入模型部署FastGPT新建FastGPT对话应用新建 FastGPT 知识库应用 部署OneAPI 拉取镜像 docker pull justsong/one-api创建挂载目录 mkdir -p /usr/local/docker/oneapi启动容器 docker run --name one-api -d …

解决 Xshell 等工具连接虚拟机失败

这里以 Xshell 等工具连接 Linux 虚拟机为例 对于我们使用 Xshell 等工具连接虚拟机失败&#xff0c;我们可以从以下的几个方面进行检查和解决 检查连接工具中的连接会话配置是否正确 对于这方面&#xff0c;我们要检查连接工具中连接会话配置的虚拟机 IP 地址和端口号是否正…