浅析Swift中枚举的内存布局
对于一般的定义方式:
enum Direction { case north, south, east, west }
对于内存的打印,我使用的github上的工具(工具连接),并且打印对象的分配大小、实际使用大小、内存对齐大小,代码如下:
var dir = Direction.north print(Mems.ptr(ofVal: &dir)) dir = .south dir = .east dir = .west print(MemoryLayout.stride(ofValue: dir)) print(MemoryLayout.size(ofValue: dir)) print(MemoryLayout.alignment(ofValue: dir))
打印结果如下:
0x00007ffeec8ef1c0 1 1 1
根据打印结果,分配内存为1个字节、实际内存为1个字节、内存对齐为1个字节
若改变声明方式,声明的时候赋值原始值
enum Direction: Int { case north = 4, south = 5, east = 6, west = 7 }
内存打印和上次一样,但是我对其进行每次赋值,为了区分从四开始赋值,每次地址打印储存值的打印情况如下:
00 00 00 00 赋值为north 01 00 00 00 赋值为south 02 00 00 00 赋值为east 03 00 00 00 赋值为weast
根据打印结果,枚举地址存储的并不是原始值
若生命值变为:
enum TestEnum { case test1(Int, Int, Int, Int) case test2(Int, Int, Int) case test3(Int) case test4(Bool) case test5 }
此时我打印内存输出结果:
0x00007ffeeadad1a0 40 33 8
总大小为40个字节 可以推算出是根据最大的test进行分配,4 个 int 32个字节,然后加上1 个字节,但是由于内存对齐需要8个字节,也就对应了总的字节数32 + 8,实际
使用的字节数32 + 1,内存对齐为8
当初始化代码为:
var dir = TestEnum.test1(1, 1, 1, 1)
01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
根据此时的内存打印对应我们之前预想的内存分配
当初始化为:
dir = TestEnum.test2(3, 3, 3)
03 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
上面大概就是枚举的内存分配