04.ISA与Class
本文基于
objc4-818.2
源码本文较长,建议吃饱喝足再进行阅读。由于很多内容关联性很强,本来准备拆分一下的。但还是决定放在一起,逐步深入。避免发生
这里一个知识点在另一篇文章,那我晚点再看(根本不会再看)
的情况。其中
协议列表
的探究过程中遇到了一些问题,无法进行下去,有解决办法的欢迎交流~
一、类对象
在上一文中我们初步探究了,obj和isa.
通过下面的步骤我们可以找到类对象
(lldb) p/x obj1
(RYObject *) $8 = 0x000000028026c340
(lldb) x/4gx 0x000000028026c340
0x28026c340: 0x000001a1042194f1 0x0000000000000000
0x28026c350: 0x0000b6106e0ac350 0x000000028356012e
(lldb) p/x 0x000001a1042194f1 & 0x0000000ffffffff8ULL
(unsigned long long) $14 = 0x00000001042194f0
(lldb) po 0x000001a1042194f1 & 0x0000000ffffffff8ULL
RYObject
1.1 类对象ISA
Class其实也是一个对象,那么我很好奇。类对象是不是也有个ISA呢?
我们以同样的步骤进行调试:
(lldb) p/x 0x000001a1042194f1 & 0x0000000ffffffff8ULL
(unsigned long long) $11 = 0x00000001042194f0
(lldb) x/4gx 0x00000001042194f0
0x1042194f0: 0x00000001042194c8 0x00000001fc942218
0x104219500: 0x00030002815641c0 0x0003801000000000
(lldb) po 0x00000001042194c8
RYObject
居然也有一个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> 的地址是 0x282af0700
2021-06-22 21:21:53.685426+0800 Class[15467:5499656] 实例<RYSubObject: 0x282af0700> 的类对象是 RYSubObject 地址是 0x10227d648
2021-06-22 21:21:53.685717+0800 Class[15467:5499656] 实例<RYSubObject: 0x282af0700> 的元类是 RYSubObject 地址是 0x10227d620
2021-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> 的地址是 0x282afc490
2021-06-22 21:21:53.685929+0800 Class[15467:5499656] 实例<RYObject: 0x282afc490> 的类对象是 RYObject 地址是 0x10227d5a8
2021-06-22 21:21:53.686703+0800 Class[15467:5499656] 实例<RYObject: 0x282afc490> 的元类是 RYObject 地址是 0x10227d580
2021-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> 的地址是 0x282afdae0
2021-06-22 21:21:53.687245+0800 Class[15467:5499656] 实例<NSObject: 0x282afdae0> 的类对象是 NSObject 地址是 0x1fc942218
2021-06-22 21:21:53.687291+0800 Class[15467:5499656] 实例<NSObject: 0x282afdae0> 的元类是 NSObject 地址是 0x1fc9421f0
2021-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 地址是0x10227d5a8
2021-06-22 21:21:53.687822+0800 Class[15467:5499656] 父类RYObject(地址0x10227d5a8)的父类是NSObject 地址是0x1fc942218
2021-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 地址是0x10227d580
2021-06-22 21:21:53.689029+0800 Class[15467:5499656] 元类RYObject(地址0x10227d580)的父类是NSObject 地址是0x1fc9421f0
2021-06-22 21:21:53.689075+0800 Class[15467:5499656] 根元类NSObject(地址0x1fc9421f0)的父类是NSObject 地址是0x1fc942218
这里发现 根元类NSObject(地址0x1fc9421f0) 的父类是 根类(地址0x1fc942218)
子类的元类
-继承-
父类的元类-继承-
根元类-继承-
根类
3.7 ISA与Class的继承关系图梳理
Last updated