经典isa走位图

分析
我们实例化的对象因为继承 由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 来分析

通过 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;
}
打印结果:

技能回顾
通过 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 的 元类。
网友评论