前言:
我们知道Swift中,对象在内存中存储结构如下图所示:
对象 的 前8个字节 指向类型信息,也就是指向 元类型(metadata)(也叫元数据) 。所以这8个字节就是一个 元类型指针
我们再看下面的Dog.self
Dog.self 也是一个 元类型(metadata)指针, 里面存放着 元类型(metadata)。 既然是指针,64bit中就占用8个字节
且 Dog.self 是 Dog.Type类型
证明1: Dog.self 也是一个 元类型(metadata)指针, 里面存放着 元类型(metadata)
通过汇编代码:
15行 是allocating ,创建Dog对象的,之后会返回堆空间地址,也就是17行中rax寄存器中存储的值。 (即:17行中的 rax 中存储着 dog对象的堆空间地址)
19行 将rax值 赋值给 0x87e(%rip) 这个全局变量 (也就是赋值给 dType),只要弄清楚此时的rax里装着什么就ok了,我们查看18行汇编会发现 rax值来自 -0x20(%rbp), 第13行会发现-0x20(%rbp)的值来自rax, rax是什么呢,可以发现是11行这个函数调用后的返回值,11行这个函数时什么呢?看注释可以知道是type metadata相关的函数,我们打印13行的rax看看是什么东西就知道了:
发现就是metadata, 这是我们写的代码 var dType: Dog.Type = Dog.self 。 那么我们就知道变量dType 存储的就是metadata, 也就是Dog.self 返回的值。
我们在查看一下对象的前8个字节 中 存放的什么,只需要打印17行的rax就可以知道对象的堆空间地址了:
再取出前8个字节,看看存储的是什么东西:
发现和Dog.self 返回的地址 一模一样, 那很好的说明,Dog.self 和 dog对象前8个字节 一样,都存储着metadata的地址
证明2: Dog.self 是 Dog.Type类型
在IDE中键入Dog.self 是提示Dog.Type, 完全可以证明Dog.self 就是 Dog.Type 类型
来源:oschina
链接:https://my.oschina.net/u/2472425/blog/4289442