在上文已经了解了SIL,接下来主要通过Swift源码和SIL剖析底层。本文主要通过底层源码探索类和对象在底层的结构
主要内容:
通过源码中探索Swift对象创建过程以及最终得到的对象结构。
通过符号断点调试来查找底层调用方法
源码:
class WYStudent { var age: Int = 18 var name: String = "WY" } var stu = WYStudent();
通过断点查看发现是通过__allocating_init()方法实现对象的创建
添加断点
查看调用方法
符号断点:
查看:
说明:
说明:
// Apple malloc is always 16-byte aligned. # define MALLOC_ALIGN_MASK 15
说明:
结构体
refCounts查看:
typedef RefCounts<InlineRefCountBits> InlineRefCounts; //是一个类,所以它的对象就是8个字节 class RefCounts { std::atomic<RefCountBits> refCounts;//引用计数 ... }
说明:
说明:
实例对象的底层结构是HeapObject结构体
默认16字节内存大小,metadata 8字节 + refCounts 8字节
metadata是类信息结构,下面会分析
refCounts是引用计数,后面也会详细分析
Swift中对象的内存分配流程是:
__ allocating_init --> swift_allocObject_ --> _swift_allocObject --> swift_slowAlloc --> malloc
对象在底层中的结构是HeapObject结构体,其第一个属性为metadata,因此从这个属性出发来查看类的结构
代码:
using HeapMetadata = TargetHeapMetaData<Inprocess>;
说明:
代码:
//模板类型 template <typename Runtime> struct TargetHeapMetadata : TargetMetadata<Runtime> { using HeaderType = TargetHeapMetadataHeader<Runtime>; TargetHeapMetadata() = default; //初始化方法 constexpr TargetHeapMetadata(MetadataKind kind) : TargetMetadata<Runtime>(kind) {} #if SWIFT_OBJC_INTEROP constexpr TargetHeapMetadata(TargetAnyClassMetadata<Runtime> *isa) : TargetMetadata<Runtime>(isa) {} #endif };
说明:
代码:
说明:
查看MetadataKind
说明:
类型
说明:
getClassObject方法:
const TargetClassMetadata<Runtime> *getClassObject() const; //******** 具体实现 ******** template<> inline const ClassMetadata * Metadata::getClassObject() const { //匹配kind switch (getKind()) { //如果kind是class case MetadataKind::Class: { // Native Swift class metadata is also the class object. //将当前指针强转为ClassMetadata类型 return static_cast<const ClassMetadata *>(this); } case MetadataKind::ObjCClassWrapper: { // Objective-C class objects are referenced by their Swift metadata wrapper. auto wrapper = static_cast<const ObjCClassWrapperMetadata *>(this); return wrapper->Class; } // Other kinds of types don't have class objects. default: return nullptr; } }
说明:
验证:
命令:
po metadata->getKind()
得到其kind是Class
po metadata->getClassObject() + x/8g 0x0000000110efdc70
这个地址中存储的是元数据信息!
说明:
注意:
代码:
template <typename Runtime> struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> { ... //swift特有的标志 ClassFlags Flags; //实力对象内存大小 uint32_t InstanceSize; //实例对象内存对齐方式 uint16_t InstanceAlignMask; //运行时保留字段 uint16_t Reserved; //类的内存大小 uint32_t ClassSize; //类的内存首地址 uint32_t ClassAddressPoint; ... }
说明:
代码:
说明: