1157 字
6 分钟
ISA与Class
ISA与Class的继承
本文基于
objc4-818.2源码
本文较长,建议吃饱喝足再进行阅读。由于很多内容关联性很强,本来准备拆分一下的。但还是决定放在一起,逐步深入。避免发生
这里一个知识点在另一篇文章,那我晚点再看(根本不会再看)的情况。
其中
协议列表的探究过程中遇到了一些问题,无法进行下去,有解决办法的欢迎交流~
一、类对象
在上一文中我们初步探究了,obj和isa.
通过下面的步骤我们可以找到类对象
(lldb) p/x obj1(RYObject *) $8 = 0x000000028026c340(lldb) x/4gx 0x000000028026c3400x28026c340: 0x000001a1042194f1 0x00000000000000000x28026c350: 0x0000b6106e0ac350 0x000000028356012e(lldb) p/x 0x000001a1042194f1 & 0x0000000ffffffff8ULL(unsigned long long) $14 = 0x00000001042194f0(lldb) po 0x000001a1042194f1 & 0x0000000ffffffff8ULLRYObject1.1 类对象ISA
Class其实也是一个对象,那么我很好奇。类对象是不是也有个ISA呢?
我们以同样的步骤进行调试:
(lldb) p/x 0x000001a1042194f1 & 0x0000000ffffffff8ULL(unsigned long long) $11 = 0x00000001042194f0(lldb) x/4gx 0x00000001042194f00x1042194f0: 0x00000001042194c8 0x00000001fc9422180x104219500: 0x00030002815641c0 0x0003801000000000(lldb) po 0x00000001042194c8RYObject居然也有一个RYObject,并且内存地址和第一步生成的0x00000001042194f0 不一样,是0x00000001042194c8。
这里的0x00000001042194c8其实就是元类。
二、元类
我们将刚才编译过的MachO丢进MachoView中解析。
打开符号表,搜索RYObject:

- _OBJC_METACLASS_RO$_RYObject
- 元类
- _OBJC_CLASS_RO$_RYObject
- 类
三、ISA与Class的关系
我们使用下面的代码进行验证,其中RYSubObject继承RYObject
RYObject *rySubObject = [[RYSubObject alloc] init]; NSLog(@"实例%@ 的地址是 %p", rySubObject, rySubObject); Class rySubObjectClass = object_getClass(rySubObject); NSLog(@"实例%@ 的类对象是 %@ 地址是 %p", rySubObject, rySubObjectClass, rySubObjectClass); Class rySubObjectMetaClass = object_getClass(rySubObjectClass); NSLog(@"实例%@ 的元类是 %@ 地址是 %p", rySubObject, rySubObjectMetaClass, rySubObjectMetaClass); Class rySubObjectRootMetaClass = object_getClass(rySubObjectMetaClass); NSLog(@"实例%@ 的根元类是 %@ 地址是 %p", rySubObject, rySubObjectRootMetaClass, rySubObjectRootMetaClass);
NSLog(@"\n");
RYObject *ryObject = [[RYObject alloc] init]; NSLog(@"实例%@ 的地址是 %p", ryObject, ryObject); Class ryObjectClass = object_getClass(ryObject); NSLog(@"实例%@ 的类对象是 %@ 地址是 %p", ryObject, ryObjectClass, ryObjectClass); Class ryObjectMetaClass = object_getClass(ryObjectClass); NSLog(@"实例%@ 的元类是 %@ 地址是 %p", ryObject, ryObjectMetaClass, ryObjectMetaClass); Class ryObjectRootMetaClass = object_getClass(ryObjectMetaClass); NSLog(@"实例%@ 的根元类是 %@ 地址是 %p", ryObject, ryObjectRootMetaClass, ryObjectRootMetaClass);
NSLog(@"\n");
NSObject *nsObject = [[NSObject alloc] init]; NSLog(@"实例%@ 的地址是 %p", nsObject, nsObject); Class nsObjectClass = object_getClass(nsObject); NSLog(@"实例%@ 的类对象是 %@ 地址是 %p", nsObject, nsObjectClass, nsObjectClass); Class nsObjectMetaClass = object_getClass(nsObjectClass); NSLog(@"实例%@ 的元类是 %@ 地址是 %p", nsObject, nsObjectMetaClass, nsObjectMetaClass); Class nsObjectRootMetaClass = object_getClass(nsObjectMetaClass); NSLog(@"实例%@ 的根元类是 %@ 地址是 %p", nsObject, nsObjectRootMetaClass, nsObjectRootMetaClass);
NSLog(@"\n");
Class rySubSuperClass = class_getSuperclass(rySubObjectClass); NSLog(@"子类%@(地址%p)的父类是%@ 地址是%p",rySubObjectClass,rySubObjectClass, rySubSuperClass, rySubSuperClass); Class rySuperClass = class_getSuperclass(ryObjectClass); NSLog(@"父类%@(地址%p)的父类是%@ 地址是%p",ryObjectClass,ryObjectClass, rySuperClass, rySuperClass); Class nsSuperClass = class_getSuperclass(nsObjectClass); NSLog(@"根类%@(地址%p)的父类是%@ 地址是%p",nsObjectClass,nsObjectClass, nsSuperClass, nsSuperClass);
NSLog(@"\n");
Class rySubMetaSuperClass = class_getSuperclass(rySubObjectMetaClass); NSLog(@"元类%@(地址%p)的父类是%@ 地址是%p",rySubObjectMetaClass,rySubObjectMetaClass, rySubMetaSuperClass, rySubMetaSuperClass); Class ryMetaSuperClass = class_getSuperclass(ryObjectMetaClass); NSLog(@"元类%@(地址%p)的父类是%@ 地址是%p",ryObjectMetaClass,ryObjectMetaClass, ryMetaSuperClass, ryMetaSuperClass); Class nsMetaSuperClass = class_getSuperclass(nsObjectMetaClass); NSLog(@"根元类%@(地址%p)的父类是%@ 地址是%p",nsObjectMetaClass,nsObjectMetaClass, nsMetaSuperClass, nsMetaSuperClass);依次得到输出如下
3.1 子类ISA
2021-06-22 21:21:53.685253+0800 Class[15467:5499656] 实例<RYSubObject: 0x282af0700> 的地址是 0x282af07002021-06-22 21:21:53.685426+0800 Class[15467:5499656] 实例<RYSubObject: 0x282af0700> 的类对象是 RYSubObject 地址是 0x10227d6482021-06-22 21:21:53.685717+0800 Class[15467:5499656] 实例<RYSubObject: 0x282af0700> 的元类是 RYSubObject 地址是 0x10227d6202021-06-22 21:21:53.685782+0800 Class[15467:5499656] 实例<RYSubObject: 0x282af0700> 的根元类是 NSObject 地址是 0x1fc9421f0
子类实例对象
-isa-子类-isa-子类元类-isa-根元类
3.2 父类ISA
2021-06-22 21:21:53.685876+0800 Class[15467:5499656] 实例<RYObject: 0x282afc490> 的地址是 0x282afc4902021-06-22 21:21:53.685929+0800 Class[15467:5499656] 实例<RYObject: 0x282afc490> 的类对象是 RYObject 地址是 0x10227d5a82021-06-22 21:21:53.686703+0800 Class[15467:5499656] 实例<RYObject: 0x282afc490> 的元类是 RYObject 地址是 0x10227d5802021-06-22 21:21:53.686760+0800 Class[15467:5499656] 实例<RYObject: 0x282afc490> 的根元类是 NSObject 地址是 0x1fc9421f0
实例对象
-isa-类-isa-元类-isa-根元类
3.3 根类ISA
2021-06-22 21:21:53.687198+0800 Class[15467:5499656] 实例<NSObject: 0x282afdae0> 的地址是 0x282afdae02021-06-22 21:21:53.687245+0800 Class[15467:5499656] 实例<NSObject: 0x282afdae0> 的类对象是 NSObject 地址是 0x1fc9422182021-06-22 21:21:53.687291+0800 Class[15467:5499656] 实例<NSObject: 0x282afdae0> 的元类是 NSObject 地址是 0x1fc9421f02021-06-22 21:21:53.687384+0800 Class[15467:5499656] 实例<NSObject: 0x282afdae0> 的根元类是 NSObject 地址是 0x1fc9421f0
根类实例对象
-isa-根类-isa-根元类-isa-根元类
3.4 ISA关系图
我们将上面的三组关系整合一下

3.5 类继承关系
2021-06-22 21:21:53.687691+0800 Class[15467:5499656] 子类RYSubObject(地址0x10227d648)的父类是RYObject 地址是0x10227d5a82021-06-22 21:21:53.687822+0800 Class[15467:5499656] 父类RYObject(地址0x10227d5a8)的父类是NSObject 地址是0x1fc9422182021-06-22 21:21:53.688283+0800 Class[15467:5499656] 根类NSObject(地址0x1fc942218)的父类是(null) 地址是0x0子类
-继承-父类-继承-根类-继承-空
3.6 元类继承关系
2021-06-22 21:21:53.688982+0800 Class[15467:5499656] 元类RYSubObject(地址0x10227d620)的父类是RYObject 地址是0x10227d5802021-06-22 21:21:53.689029+0800 Class[15467:5499656] 元类RYObject(地址0x10227d580)的父类是NSObject 地址是0x1fc9421f02021-06-22 21:21:53.689075+0800 Class[15467:5499656] 根元类NSObject(地址0x1fc9421f0)的父类是NSObject 地址是0x1fc942218这里发现 根元类NSObject(地址0x1fc9421f0) 的父类是 根类(地址0x1fc942218)
子类的元类
-继承-父类的元类-继承-根元类-继承-根类
3.7 ISA与Class的继承关系图梳理
