isa 走位&类对象&元类

2020-09-16  本文已影响0人  猿人

经典isa走位图

2251862-48a5603729fdf0a9.png

分析
我们实例化的对象因为继承 由objc_object 结构体模板 所以里面 有isa。isa是一个 8字节64个二进制位的 联合体,他的位域 也告诉了我们 class其所占用的位置及大小 。 x86 shiftcls:44 arm64:33 。 底层mask面具 define ISA_MASK 0x00007ffffffffff8ULL

通过 lldb 及源码 来分析 这张经典走位图

int main(int argc, const char * argv[]) {
    @autoreleasepool {
  

        LGPerson *person = [LGPerson alloc];

        NSLog(@"Hello, World!");
    }
    return 0;
}

首先创建一个 继承 NSObjcet 的 LGPerson 进行初始化 并断在 NSlog 来分析

截屏2020-09-16上午11.43.03.png

通过 runTime Api 来分析 这张经典走位图

int main(int argc, const char * argv[]) {
    @autoreleasepool {
  

        LGPerson *person = [LGPerson alloc];
        /// 根据person实例 获取 类对象
        Class pclass =   object_getClass(person);
        /// 获取 类对象的 元类
//        Class objc_meta_class    =  object_getClass(pclass);;
        
        Class  objc_meta_class   = objc_getMetaClass(object_getClassName(person));
        
        
        /// 获取元类 isa 走向 指向  跟元类 class
//       Class rootMetaClass = object_getClass(objc_meta_class);
         Class  rootMetaClass   = objc_getMetaClass(object_getClassName(objc_meta_class));

        
        /// 获取 根元类的 isa 指向class
//        Class rtMetaClass = object_getClass(rootMetaClass);
        Class  rtMetaClass   = objc_getMetaClass(object_getClassName(rootMetaClass));

 
         NSLog(@"%@ - %p - %p - %p - %p",person,pclass,objc_meta_class,rootMetaClass,rtMetaClass);
         NSLog(@"%@ - %@ - %@ - %@ - %@",person,pclass,objc_meta_class,rootMetaClass,rtMetaClass);


        NSLog(@"Hello, World!");
    }
    return 0;
}

打印结果:


截屏2020-09-16下午1.31.50.png

技能回顾

通过 clang 命令 编译 .cpp文件 查看源码 LGPerson 为线索 搜索cpp源码文件 得到下面线索

#ifndef _REWRITER_typedef_LGPerson
#define _REWRITER_typedef_LGPerson
typedef struct objc_object LGPerson;
typedef struct {} _objc_exc_LGPerson;
#endif

struct LGPerson_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
};

那 NSObject_IMPL 又是什么?

struct NSObject_IMPL {
    Class isa;
};

看到 了 isa 是Class 类型
还搜到了 一个

 typedef struct objc_object LGPerson

objc_object 又是什么? 带着疑问我们来到 objc源码 它或许可以为我们解答

首先好奇的 搜索 Class 随便点一个 点进去最终到了这里 并继续点击 objc_class

typedef struct objc_class *Class;
typedef struct objc_object *id;

/// 点击 objc_class 跳到这里

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() const {
        return bits.data();
    }
    ......  后面太多省略
}
 

发现 Class 的类型是 objc_class 类型 的结构体 objc_class 继承自 objc_object ; command + 点击 objc_object 深入 点不进去 好吧 全局搜索源码

struct objc_object {
private:
    isa_t isa;

public:

    // ISA() assumes this is NOT a tagged pointer object
    Class ISA();

    // rawISA() assumes this is NOT a tagged pointer object or a non pointer ISA
    Class rawISA();

  ...... 后面太多忽略
}

我的天 objc_object 里面 有 isa 我们还记得 对象[LGPerson alloc] 流程最重要的三部曲 计算内存空间 开辟 内存空间 绑定 isa isa 的类型 是 isa_t的结构体

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};

总结

万物皆对象 : 盘古开天辟地以来 制造万物 均由 objc_object 结构体 模板而来 它与生俱来 有isa
isa 本质是一个8字节 64位的联合体,再它的位域 里面 又存有 它所指向类的 (objc_class ) 信息
x86下:shiftcls: 44字节 arm64: 33字节
而 类对象(objc_class)也是继承自 objc_object 它的isa 里面一样存有它所指向的类 也就是 元类。
元类是一个 抽象类 而 元类 一样继承自 objc_object 它的isa 里面 一样存有它 所指向的类 那么 就是 根元类, 也就是 NSObjcet. 注意:这里的NSObjcet 是根元类。 它是 NSObjcet class 的 元类。

上一篇 下一篇

猜你喜欢

热点阅读