美文网首页
Swift - String、Array的内存分配情况

Swift - String、Array的内存分配情况

作者: Sweet丶 | 来源:发表于2022-09-11 17:45 被阅读0次

Swift中,StringArray是结构体类型,而结构体是值类型,值类型的内容就放在自身变量中,自身变量的大小是在声明后就固定的;但是我们知道当它们被声明为var类型时,如果一直往里面追加元素,自身变量中肯定会到达存不下的时候,那么String、Array是怎么存放里面元素的?

public struct Array<Element> {}
public struct String {}
一、String是怎么存放里面元素的?

下面代码中的Mems是一个打印变量地址和变量内容的工具,工具地址。下面是代码探索的总结:

  • 字符串变量占用16个字节。
  • 15个字符以内的字符串是以ASCII码值放在字符串变量中的,其中后8个字节中的最后一个字节0xe9中9代表个数,0xe可以认为是一个类型标记。
  • 当字符串个数超过15时,会开辟堆空间来存放字符串内容,而变量中的后8个字节存放的这个堆空间的地址, 前8个字节中有跟类型相关和字符串长度相关的内容。
  • 堆空间中前32个字节之后才是字符串的内容。
func testString()  {
//    // 字符15及以内的字符串变量是占16个字节
//    var tagPointStr = "123456789"
//    // 0x3837363534333231 0xe900000000000039
//    // 字符串15位及以内是以ASCII码放在变量内的,
//  0xe9中9代表个数,0xe可以认为是一个标记
//    print(Mems.memStr(ofVal: &tagPointStr))
    
    // 超出15位字符时,变量的值就变了
    // 0xd000000000000010 0x80000001049e6a40 这个值是与字符串的值没有关系的
    // 后八个字节0x80000001049e6a40是字符串的真实地址值 + 一个固定的值,所以通过后八个字节可以找到字符串真实地址。
    // 前面8个字节0xd000000000000010中的10是字符串长度,0xd是相当于一个标识位
    // 字符串初始化会调用init方法参数有字符串的真实地址、字符串的长度。在初始化时判断长度是否大于15
    var string: String = "0123456789ABCDEF"
    print(Mems.memStr(ofVal: &string))
    
    // 通过字面量创建的字符串是放在_text段的常量区,并且可以通过mach-o View工具来查看
    
    var str11 = "0123456789ABCDE"
    // 当字符串变量长度大于15后,再次追加字符串,系统会分配堆空间来存储字符串的值
    // 在字符串变量中存储的值变为前8字节是类型和字符串长度信息,后8字节是字符串堆空间的地址值,
    // 而字符串开始的位置为堆空间地址 + 0x20,即跳过前32个字节
    str11.append("F")
    
    /* dyld_stub_binder函数的作用
     在程序启动时,Mach-o文件会加载到内存中,然后会加载所依赖的动态库mach-o文件到内存中;
     我们本身程序中对于系统库的具体函数调用,会在第一次调用时,
     调用dyld_stub_binder去加载动态库中真实对应的函数的地址进行绑定,然后再调用;
     相当于把系统动态库函数的调用放到了运行时决定。
    */
}
二、Array是怎么存放元素的?
func testArrayDeep() {
    
    var arrT: Array<Int> = [6, 7, 8, 9, 10, 11]
    print("ptr(ofVal", Mems.ptr(ofVal: &arrT)) // 这里打印的是arrT变量的地址0x0000000103010d38
    print("ptr(ofRef", Mems.ptr(ofRef: arrT)) //打印的是arrT指向的内存地址0x0000000102fffc78
    // 通过lldb打印指令,x/10xg打印地址可以发现:
    // 0x0000000102fffc78是一个堆空间的地址,
    // 前32个字节中,8个字节未知,8个字节代表引用计数,8个字节代表元素个数,8个字节代表数组容量相关
  // 32个字节之后开始是数组的元素值
} 

相关文章

网友评论

      本文标题:Swift - String、Array的内存分配情况

      本文链接:https://www.haomeiwen.com/subject/kbxfortx.html