美文网首页内存OC 底层
【iOS-RunTime系列二】isa指针

【iOS-RunTime系列二】isa指针

作者: GeniusWong | 来源:发表于2018-09-20 23:08 被阅读13次
    • runTime底层的一些常用数据结构,比如isa指针;
    • arm64之前,isa就是一个普通的指针,存储着ClassMeta-Class对象的内存地址,
    • arm64开始,对isa进行了优化,变成了一个共同体 union结构, isa & ISA_MASK才得到真实地址值;
    • 看一下底层 objc_object

    struct objc_object {
    private:
        isa_t isa;//  32位的时候是 `Class` ,现在变成了 `union`
    
    • 64位开始,变成了共同体;
    • Class 、Meta-Class 对象的内存地址的二进制后3位一定是000
    • 在arm64前, isa 就是一个普通指针,存储着Class、Meta-Class对象指针;
    • arm64后,使用 union 结构,将一个64位的内存空间存储了很多内容,其中的33位存储着Class、Meta-Class对象指针地址值 ;
    union isa_t 
    {
            Class cls;
            uintptr_t bits; //  这是一个 unsigned long 型,
    struct {
            uintptr_t nonpointer        : 1;  //  0 代表普通的指针,存储着Class、Meta-Class对象的内存地址;  1代表优化过,使用位域存储更多的信息
            uintptr_t has_assoc         : 1;  // 是否有设置过关联对象,如果没有,释放时会更快
            uintptr_t has_cxx_dtor      : 1;  //  是否有C++的析构函数,如果没有释放时会更快
            uintptr_t shiftcls          : 33; //  存储着Class、Meta-Class 对象的内存地址信息 MACH_VM_MAX_ADDRESS 0x1000000000
            uintptr_t magic             : 6;  //  用于在调度时分辨对象是否未完成初始化
            uintptr_t weakly_referenced : 1;  //  是否有被弱引用指向过,如果没有,释放会更快
            uintptr_t deallocating      : 1;  //  对象是否正在释放
            uintptr_t has_sidetable_rc  : 1;  //  里面存储的值是引用计数器减1
            uintptr_t extra_rc          : 19; //  引用计数是否过大无法存储在isa中; 如果为1,那么引用计数会存储在一个叫SideTable的类的属性中 
    #       define RC_ONE   (1ULL<<45)
    #       define RC_HALF  (1ULL<<18)
        };
    }
    
    • bits是大家共用的
    union {
       char bits; // 1个字节 
    } _name ; 
    
    

    相关文章

      网友评论

        本文标题:【iOS-RunTime系列二】isa指针

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