通过分析对象的本质得知实例对象的isa指向类对象,那类对象的isa呢,我们接下来就对 isa 的流程进行分析。
定义一个 SHPerson 对象,在 main 函数初始化并断点调试。
lldb打印结果如下:
接下来,将对这三个内存地址进行研究:
0x00000001000080e8
0x00000001000080c0
0x00000001003790f0
当然,这个内存地址是可能会变的,具体需要自己根据断点进行lldb打印。
使用MachOView打开代码的可执行文件(exec)。
找到符号表,并且滚动到黄褐色的部分。
发现,00000001000080E8,
00000001000080C0的内存地址不就是上面提到要研究的么,再根据value这一列的值,就可以得知,0x00000001000080e8是类对象,
0x00000001000080c0是元类对象,那么0x00000001003790f0是什么?
0x00000001003790f0是一个叫根元类对象的东西。
总结如下:
实例对象的isa指向类对象,类对象的isa指向元类对象,元类对象的isa指向根元类对象,根元类对象的isa指向的是自己本身。
类对象,元类对象,根元类对象是否也有继承链呢?如果有,是怎么样的一个继承链呢?添加一个继承至SHPerson的SHStudent类。
并且为了方便理解,下面暂时先把SHStudent比作子类(subClass),SHPerson比作父类(superClass),NSObject比作根类(rootClass)。
1. runtime部分API介绍。
导入 #import <objc/runtime.h>
objc_getClass和objc_getMetaClass先作为了解,因为object_getClass就可以拿到类对象,元类对象,根元类对象,并且,更多runtime的API官方文档都有介绍。以下探索主要用到object_getClass和class_getSuperclass。
2. 使用 runtime API 打印输出
//1. 子类的instance对象isa流程和继承链。
NSLog(@"子类(SHStudent)打印");
SHStudent *student = [[SHStudent alloc] init];
// class对象
Class class_student = object_getClass(student);
// metaclass对象
Class metaclass_student = object_getClass(class_student);
// rootMetaclass对象
Class rootMetaclass_student = object_getClass(metaclass_student);
NSLog(@"class_student : %@ - %p",class_student, class_student);
NSLog(@"metaclass_student : %@ - %p",metaclass_student, metaclass_student);
NSLog(@"rootMetaclass_student: %@ - %p",rootMetaclass_student, rootMetaclass_student);
NSLog(@"------------------");
// class对象的superclass对象
Class superclass_student = class_getSuperclass(class_student);
// metaclass对象的superclass对象
Class superMetaclass_student = class_getSuperclass(metaclass_student);
// rootMetaclass对象的superclass对象
Class superRootMetaclass_student = class_getSuperclass(rootMetaclass_student);
NSLog(@"superclass_student : %@ - %p",superclass_student, superclass_student);
NSLog(@"superMetaclass_student : %@ - %p",superMetaclass_student, superMetaclass_student);
NSLog(@"superRootMetaclass_student: %@ - %p",superRootMetaclass_student, superRootMetaclass_student);
//2. 父类的instance对象isa流程和继承链。
NSLog(@"");
NSLog(@"父类(SHPerson)打印");
SHPerson *person = [[SHPerson alloc] init];
// class对象
Class class_person = object_getClass(person);
// metaclass对象
Class metaclass_person = object_getClass(class_person);
// rootMetaclass对象
Class rootMetaclass_person = object_getClass(metaclass_person);
NSLog(@"class_person : %@ - %p",class_person, class_person);
NSLog(@"metaclass_person : %@ - %p",metaclass_person, metaclass_person);
NSLog(@"rootMetaclass_person: %@ - %p",rootMetaclass_person, rootMetaclass_person);
NSLog(@"------------------");
// class对象的superclass对象
Class superclass_person = class_getSuperclass(class_person);
// metaclass对象的superclass对象
Class superMetaclass_person = class_getSuperclass(metaclass_person);
// rootMetaclass对象的superclass对象
Class superRootMetaclass_person = class_getSuperclass(rootMetaclass_person);
NSLog(@"superclass_person : %@ - %p",superclass_person, superclass_person);
NSLog(@"superMetaclass_person : %@ - %p",superMetaclass_person, superMetaclass_person);
NSLog(@"superRootMetaclass_person: %@ - %p",superRootMetaclass_person, superRootMetaclass_person);
//3. 根类的instance对象isa流程和继承链。
NSLog(@"");
NSLog(@"根类(NSObject)打印");
NSObject *object = [[NSObject alloc] init];
// class对象
Class class_object = object_getClass(object);
// metaclass对象
Class metaclass_object = object_getClass(class_object);
// rootMetaclass对象
Class rootMetaclass_object = object_getClass(metaclass_object);
NSLog(@"class_object : %@ - %p",class_object, class_object);
NSLog(@"metaclass_object : %@ - %p",metaclass_object, metaclass_object);
NSLog(@"rootMetaclass_object: %@ - %p",rootMetaclass_object, rootMetaclass_object);
NSLog(@"------------------");
// class对象的superclass对象
Class superclass_object = class_getSuperclass(class_object);
// metaclass对象的superclass对象
Class superMetaclass_object = class_getSuperclass(metaclass_object);
// rootMetaclass对象的superclass对象
Class superRootMetaclass_object = class_getSuperclass(rootMetaclass_object);
NSLog(@"superclass_object : %@ - %p",superclass_object, superclass_object);
NSLog(@"superMetaclass_object : %@ - %p",superMetaclass_object, superMetaclass_object);
NSLog(@"superRootMetaclass_object: %@ - %p",superRootMetaclass_object, superRootMetaclass_object);
(滑动显示更多)
3. lldb打印分析
红色箭头代表类对象的继承链,黄色箭头代表元类对象的继承链,绿色箭头代表根元类对象的继承链。
从图得知:
结合下面的一张很经典的图,就更清楚了。
这种是一张广为流传并且很经典的图,这张图描述isa的流程以及class的继承链,通过以上的分析再来看这种图就有种豁然开朗的感觉,以前总看不懂这张。
其实不管是子类、父类、根类isa的流程和类的继承链都基本是一样的,真正的不同在于根元类对象(rootMetaclass)这个地方,isa的流程到这儿,isa指针再怎么指都是根元类对象自己,并且根元类对象的父类是根类,而根类对象的父类是一个nil。
原文链接:https://juejin.cn/post/7038460181121859597
本文分享自 HelloCoder全栈小集 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!