IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS-深入理解NSString的三种存储类型 -> 正文阅读

[移动开发]iOS-深入理解NSString的三种存储类型

前瞻

在 Objective-C 的 Fondation 框架中 NSString 对象是很复杂的存在,各种方式创建以及不同长度的字符串都会影响 NSString 对象在内存中所处的位置。Objective-C 在运行时也对其做了很多优化。今天就来研究一下 NSString 这个复杂的对象。

NSString 类型的出现

  • 参考学长的博客,我们以四个字符串为例,分别用 @ 直接创建两个长短不一的,再分别用 stringWithFormat 创建两个长短不一的
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString* string1 = @"hello3GiOS";
        NSString* string2 = @"hello";
        NSString* string3 = [NSString stringWithFormat:@"hello3GiOS"];
        NSString* string4 = [NSString stringWithFormat:@"hello"];
        
        NSLog(@" \n%@ %p\n, %@ %p\n, %@ %p\n, %@ %p\n, ", [string1 class], string1, [string2 class], string2, [string3 class], string3, [string4 class], string4 );
    }
    return 0;
}
  • 打印结果

在这里插入图片描述

  • 我们发现对于用@ 直接创建的字符串的类型与长短无关
  • 但是用stringWithFormat 创建的字符串产生的类型就和长短有关

__NSCFConstantString

对于这个类型的NSString,我们测试打印他的retainCount

  NSString* string1 = @"hello3GiOS";
        NSString* string2 = @"hello";
        NSLog(@" string1的引用计数: %ld", CFGetRetainCount((__bridge  CFTypeRef)(string1)));
        NSLog(@" string2的引用计数: %ld", CFGetRetainCount((__bridge  CFTypeRef)(string2)));

请添加图片描述

  • 发现二者的引用计数是很大很大的数字,我们是ARC环境下(也即是自动释放池)进行测试的,如此一来说明他们不能被释放。
    它是创建之后便是放不掉的对象
    我们创建两个内容相同的对象试试
   NSString* string1 = @"hello3GiOS";
//        NSString* string2 = @"hello";
        NSString* string = @"hello3GiOS";
        NSLog(@"string1的地址:%p, string的地址 %p", string1, string);

请添加图片描述

在这里插入图片描述

  • 上面创建了两个内容,类型相同的字符串,结果发现他们的地址是相同的,这也就说明了 __NSCFConstantString 是一种创建以后无法被释放的单例
怎么出现__NSCFConstantString
  • 查阅资料
    • 上面测试的@“…” 可以产生 __NSCFConstantString
    • CFSTR(“…”) 可以产生 __NSCFConstantString
    • stringWithString 可以产生 __NSCFConstantString (此方法等同于@“…”) 可以忽略。

__NSCFString

  • 同样的打印 __NSCFString 的引用计数 和类型来测试
 NSString* string3 = [NSString stringWithFormat:@"hello3GiOS"];
        NSString* textString = [NSString stringWithFormat:@"hello3GiOS"];
        NSLog(@"string3的地址:%p 类型 %@, textString的地址 %p 类型 %@", string3,[string3 class], textString, [textString class]);
  • 类型和地址
    • 创建两个内容一样的 __NSCFString 他们的地址是不一样的
      在这里插入图片描述
  • 引用计数
    在这里插入图片描述
  • 查阅资料
  • 和 __NSCFConstantString 不同, __NSCFString 对象是在运行时创建的一种 NSString 子类,他并不是一种字符串常量。所以和其他的对象一样在被创建时获得了 1 的引用计数。
    通过 NSString 的 stringWithFormat 等方法创建的 NSString 对象一般都是这种类型(长度大于等于9)
NSTaggedPointerString
  • 测试类型,同一个内容的地址和引用计数
 NSString* string4 = [NSString stringWithFormat:@"hello"];
        NSString* testString = [NSString stringWithFormat:@"hello"];
        NSLog(@" string4的引用计数: %ld", CFGetRetainCount((__bridge  CFTypeRef)(string4)));
        NSLog(@" test的引用计数: %ld", CFGetRetainCount((__bridge  CFTypeRef)(testString)));
        NSLog(@"string4的地址:%p 类型 %@, teststring的地址 %p 类型 %@", string4, [string4 class], testString, [testString class]);

在这里插入图片描述

  • 可以看到NSTaggedPointerString 也是一种单例并且一旦创建就不会被释放
  • 查阅资料
  • 对于 NSString 对象来讲,当非字面值常量的数字,英文字母字符串的长度小于等于 9 的时候会自动成为 NSTaggedPointerString 类型,如果有中文或其他特殊符号(可能是非 ASCII 字符)存在的话则会直接成为 )__NSCFString 类型。
  • 转载博客
  • 理解这个类型,需要明白什么是标签指针,这是苹果在 64 位环境下对 NSString,NSNumber 等对象做的一些优化。简单来讲可以理解为把指针指向的内容直接放在了指针变量的内存地址中,因为在 64 位环境下指针变量的大小达到了 8 位足以容纳一些长度较小的内容。于是使用了标签指针这种方式来优化数据的存储方式,在运行时根据实际情况创建。
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-06-20 23:05:27  更:2022-06-20 23:05:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 2:57:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码