美文网首页专注iOS开发的小渣渣
swift底层探索 01 - 类初始化&类结构

swift底层探索 01 - 类初始化&类结构

作者: Henry________ | 来源:发表于2020-12-11 10:30 被阅读0次

    探索swift可以通过:源码调试Sil文件xcode断点调试这些方式来进行探索,除Sil文件这种方式其他的都会在本文中出现。OC底层探索01-找到底层探索的钥匙会有解释。

    探索路径同样是参考oc的探索路径,先从类开始。

    类初始化

    1. 使用Xcodel断点调试

    • 创建一个简单的类,开启汇编断点
    • 1步骤就是__allocation_initswift对象初始化入口
    • 通过2步骤可以进入下一步(下断点,按住control+↓)
    • swift_allocObject是初始化第二步
    • 下断点,按住control+↓进入下一步
    • swift_slowAlloc是初始化第三步
    • 下断点,按住control+↓进入下一步

    • malloc_zone_malloc是初始化第四步,在这一步完成内存的分配,最终完成alloc步骤

    2. 使用源码调试

    现在通过源码调试来验证一下之前的论点。源码编译方式Swift-5.3.1 源码编译.

    static HeapObject *_swift_allocObject_(HeapMetadata const *metadata,
                                           size_t requiredSize,
                                           size_t requiredAlignmentMask) {
      assert(isAlignmentMask(requiredAlignmentMask));
      //swift慢速创建流程
      auto object = reinterpret_cast<HeapObject *>(
          swift_slowAlloc(requiredSize, requiredAlignmentMask));
      //为创建好的内存赋值
      new (object) HeapObject(metadata);
    
      SWIFT_LEAKS_START_TRACKING_OBJECT(object);
    
      SWIFT_RT_TRACK_INVOCATION(object, swift_allocObject);
    
      return object;
    }
    
    void *swift::swift_slowAlloc(size_t size, size_t alignMask) {
      void *p;
      
      //一般使用 8字节对齐 
      //#  define MALLOC_ALIGN_MASK 15
      if (alignMask <= MALLOC_ALIGN_MASK) {
    #if defined(__APPLE__)
        //apple的类会进入这里
        p = malloc_zone_malloc(DEFAULT_ZONE(), size);
    #else
        p = malloc(size);
    #endif
      } else {
      //大于16字节对齐的情况,比较少见
        size_t alignment = (alignMask == ~(size_t(0)))
                               ? _swift_MinAllocationAlignment
                               : alignMask + 1;
        p = AlignedAlloc(size, alignment);
      }
      if (!p) swift::crash("Could not allocate memory.");
      return p;
    }
    
    • 根据源码也可以跟到具体的流程
    • alignMask <= MALLOC_ALIGN_MASK进入这个判断可以看出swift类一般使用的是8字节对齐
    #define malloc_zone_malloc(zone,size) malloc(size)
    
    • malloc_zone_malloc只是一个宏定义,最终调用malloc

    3. 初始化流程图

    类结构 - HeapObject结构

    1. 编译器断点

    • 在进行类创建,源码调试的时候发现swift的类结构是这样的。和oc比起来是有一些不同的。我们换种方式看看.

    2. lldb

    • 相比于OC不同的是,除了第一位之外,还将引用计数当做第二个参数保存到对象中

    3. 源码查看

    swift对象继承自HeapObject

    struct HeapObject {
      /// This is always a valid pointer to a metadata object.
      HeapMetadata const *metadata;
    
    //#define SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS       \
      InlineRefCounts refCounts
      SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;
      
      ...
    }
    

    swift-类的结构图

    HeapMetadata结构

    如果说metaData相比于oc对象中的isa的而言的话,应该要包含isa,superclass,cache_t,date等类的信息。我们就来看看HeapMetadata结构都有些什么呢~

    //相当于宏定义 
    using HeapMetadata = TargetHeapMetadata<InProcess>
    
    //template 模板类
    struct TargetHeapMetadata : TargetMetadata<InProcess>{
        。。。
    }
    
    struct TargetMetadata<InProcess>{
        StoredPointer Kind; //用来区分是什么类型的原数据 
    
    //一个相关的方法
        getObjCClassObject() const {
        return reinterpret_cast<Class>(
          const_cast<TargetClassMetadata<InProcess>*>(
            getClassObject()));
      }
    }
    
    • TargetHeapMetadata是一个模板类,想要了解内部结构需要继续向下查看
    • <InProcess>类似于泛型,限制泛型的具体类型
    • 没有看到其他相关定义,只能借助其他方式来查看getClassObject

    借助getClassObject方法查看HeapMetadata结构

    //获取类对象
      Metadata::getClassObject() const {
        switch (getKind()) {
        case MetadataKind::Class: {
          return static_cast<const ClassMetadata *>(this);
        }
        //如果是类,指针强转为ClassMetadata
        case MetadataKind::ObjCClassWrapper: {
          auto wrapper = static_cast<const ObjCClassWrapperMetadata *>(this);
          return wrapper->Class;
        }
          return nullptr;
        }
      }
    
    • 我们发现将当前指针强转为ClassMetadata。指针可以强转则表示内部结构是相同的,我们可以转换角度去查看ClassMetadata.

    ClassMetadata

    using ClassMetadata = TargetClassMetadata<InProcess>;
    struct TargetClassMetadata : TargetAnyClassMetadata<Runtime> {
        ClassFlags Flags;
        uint32_t InstanceAddressPoint;
        uint32_t InstanceSize;
        ...
    }
    
    struct TargetAnyClassMetadata : TargetHeapMetadata
    {
      ConstTargetMetadataPointer  Superclass;
      TargetPointer CacheData[2];
      StoredSize Data;
      ...
    }
    

    元类结构图

    swift类结构.png

    相关文章

      网友评论

        本文标题:swift底层探索 01 - 类初始化&类结构

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