美文网首页
Runtime源码理解isa

Runtime源码理解isa

作者: 风雨彩虹_123 | 来源:发表于2021-09-24 10:10 被阅读0次

    在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-Class对象的内存地址。
    在Runtime源码中可以看到

    /// Represents an instance of a class.
    struct objc_object {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    };
    

    从arm64架构开始,对isa进行了优化,变成了一个共用体(unit)结构,还使用位域来存储更多的信息
    在Runtime源码中可以看到

    struct objc_object {
    private:
        isa_t isa;
    }
    //共用体中可以定义多个成员,共用体的大小由最大的成员大小决定
    //共用体的成员公用一个内存
    //对某一个成员赋值,会覆盖其他成员的值
    //存储效率更高
    union isa_t 
    {
        isa_t() { }
        isa_t(uintptr_t value) : bits(value) { }
        Class cls;
        uintptr_t bits;   //存储下面结构体每一位的值
    #if SUPPORT_PACKED_ISA
    # if __arm64__
    #   define ISA_MASK        0x0000000ffffffff8ULL
    #   define ISA_MAGIC_MASK  0x000003f000000001ULL
    #   define ISA_MAGIC_VALUE 0x000001a000000001ULL
        struct {
            uintptr_t nonpointer        : 1;
            uintptr_t has_assoc         : 1;
            uintptr_t has_cxx_dtor      : 1;
            uintptr_t shiftcls          : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
            uintptr_t magic             : 6;
            uintptr_t weakly_referenced : 1;
            uintptr_t deallocating      : 1;
            uintptr_t has_sidetable_rc  : 1;
            uintptr_t extra_rc          : 19;
    #       define RC_ONE   (1ULL<<45)
    #       define RC_HALF  (1ULL<<18)
        };
    }
    

    nonpointer

    表示是否对 isa 指针开启指针优化
    0:表示普通指针,存储着Class、Meta-Class对象的内存地址
    1:表示优化过的指针,使用位域存储更多的信息,包含是否有关联对象、对象的引用计数、是否有弱引用、是否使用C++代码等等。

    has_assoc

    关联对象标志位,0没有,1存在
    是否有设置过关联对象,关联对象被取消,值任然为1

    has_cxx_dtor

    是否有C++的析构函数 0 没有,对象释放时会更快 1 有 需要做析构的逻辑处理

    shiftcls

    存储着Class、Meta-Class对象的内存地址

    magic

    用于调试器判断当前对象是真的对象还是没有初始化的空间

    weakly_referenced

    是否设置过被弱引用指向过 0 没有,对象释放时会更快 1 有,对象释放时,runtime会将所以指向该对象的弱引用置为nil,
    只要被弱引用指向过,其值就是1

    deallocating

    标志对象是否正在释放内存

    has_sidetable_rc

    是否有外挂的引用计数表, 0 没有 1 有,当对象的引用计数大于10是,则需要外挂引用计数表来管理对象

    extra_rc

    存储对象的引用计数,值为引用计数器减一,因为在获取对象的引用计数的方法中,系统会做加一处理。

    相关文章

      网友评论

          本文标题:Runtime源码理解isa

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