关于String的思考

1个String变量占用多少内存?
下面两个String变量,底层存储有什么不同?

  1. var str1 = "0123456789"
  2. var str2 = "0123456789ABCDEF"

image.png
如果对String进行拼接操作,String变量的存储会发生什么变化?

  1. str1.append("ABCDE")
  2. str1.append("F")
  3. str2.append("G")

查看str1内存

  1. var str1 = "0123456789"

可以通过汇编查看str1内部16个字节保存的内容:
image.png
分别打印rcx和rdx两个寄存器中的内容

  1. (lldb) register read rcx
  2. rcx = 0x3736353433323130
  3. (lldb) register read rdx
  4. rdx = 0xea00000000003938
  5. (lldb)

str1内部保存的是 0x3736353433323130 0xea00000000003938
对照ASII码:https://www.ascii-code.com/
可以发现字符 0~9的分别的十六进制值为30 ~ 39
image.png
所以str1的内存是直接保存了字符串的内容,其中0xea的作用是:
e:类型标识 a:代表字符串长度
长度最大可以用f表示,所以可以得出这种存储方式最多可以存储15个字节。
例如下面这个字符串:

  1. var str1 = "0123456789ABCDE"
  2. // 0x3736353433323130 0xef45444342413938
  3. print(Mems.memStr(ofVal: &str1))

查看str2内存

image.png

数组

  1. var arr = [1, 2, 3 , 4]
  2. print(Mems.memStr(ofRef: arr))

打印数组的内存,数组结构如下

  1. 0x00007ff84d35e208 -> ?
  2. 0x0000000200000003 -> 引用计数
  3. 0x0000000000000004 -> 元素数量
  4. 0x0000000000000008 -> 数组容量
  5. 0x0000000000000001 -> 存储的数据 1
  6. 0x0000000000000002 -> 存储的数据 2
  7. 0x0000000000000003 -> 存储的数据 3
  8. 0x0000000000000004 -> 存储的数据 4