美文网首页
isa 走位&类对象&元类

isa 走位&类对象&元类

作者: 猿人 | 来源:发表于2020-09-16 11:44 被阅读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 来分析 这张经典走位图

  • 通过object_getClass获取对象isa指针指向链
    object_getClass 参数是id类型,它返回的是这个id的isa指针所指向的Class,如果传参是Class,则返回该Class的metaClass

  • objc_getMetaClass(const char * _Nonnull name)
    objc_getMetaClass 参数 是 char* 类型 它返回的是已命名类的元类

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 的 元类。

相关文章

  • isa相关的经典面试题分析

    前言 书接上回类的结构分析,我们得知isa指针的走位:对象 --> 类 --> 元类 --> 根元类-->根元类 ...

  • isa 走位&类对象&元类

    经典isa走位图 分析我们实例化的对象因为继承 由objc_object 结构体模板 所以里面 有isa。isa是...

  • isa 和 superclass

    实例对象的 isa 指向类对象,类对象的 isa 指向元类对象,元类的isa 指向基类的元类对象,基类的元类对象的...

  • RunTime底层原理

    1.isaisa:实例对象的isa指向类对象,类对象的isa指向元类对象。元类对象isa执行基类元类对象。2.方法...

  • iOS开发中方法查找流程图

    实例对象的isa指针指向类对象,类对象的isa指针指向元类,元类的isa指针指向根元类,根元类的isa指针指向自己...

  • 类对象、元类

    任何实例的isa指针指向其类对象,类对象的isa指针指向其元类对象,元类对象的isa指针指向根元类对象,根元类对象...

  • 1、元类 我们都知道对象的isa是指向类,类其实也是一个对象,可以称为类对象,其isa的位域指向苹果定义的元类 元...

  • iOSisa指针和superclass指针

    isa指针实例对象的isa指向类对象类对象的isa指向元类对象元类对象的isa指向基类的元类如何证明上面所述可以通...

  • iOS开发 Runtime 流程图

    你了解多少Runtime? isa 指针的理解 实例对象 isa 指向类对象 类对象指 isa 向元类对象 元类对...

  • iOS 对象和isa指针详解

    一个objc对象的isa指针指向他的类对象,类对象的isa指针指向他的元类,元类的isa指针指向根元类,所有的元类...

网友评论

      本文标题:isa 走位&类对象&元类

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