在之前的文章对象内存探索中,我们已经知道对象默认都有一个isa指针,这个指针指向的正式对象的类,而在oc中一切皆为对象,那类是否也有isa指针,他的指针指向的是谁呢?
带着这个疑问我们来看看
首先我们来看一个示例:
@interface HFPerson : NSObject
@end
HFPerson *p = [HFPerson alloc];
NSLog(@"%@---%p", p, p);
通过lldb我们来打印p的isa指针指向的类
(lldb) x/4gx p
0x28189a520: 0x000001a102e2d675 0x0000000000000000
0x28189a530: 0x0000000000000000 0x0000000000000000
0x000001a102e2d675 p的isa指针
(lldb) po 0x000001a102e2d675 & 0x0000000ffffffff8ULL
HFPerson
(lldb) p/x 0x000001a102e2d675 & 0x0000000ffffffff8ULL
(unsigned long long) $11 = 0x0000000102e2d670
这边就可以清楚看到isa指针指向的是HFPerson,也就是说对象的isa指向的是类
接下来我们看看类的isa指针
(lldb) x/4gx 0x0000000102e2d670
0x102e2d670: 0x0000000102e2d648 0x00000001f65e60d8
0x102e2d680: 0x00070002838e4a00 0x0005803900000000
(lldb) po 0x0000000102e2d648 & 0x0000000ffffffff8ULL
HFPerson
(lldb) p/x 0x0000000102e2d648 & 0x0000000ffffffff8ULL
(unsigned long long) $13 = 0x0000000102e2d648
咦也是HFPerson,但是我们看到$13 跟 前面的$11不一样,也就是说有两个HFPerson类?
接下来在继续往下看看会不会有第三个HFPerson类
(lldb) x/4gx 0x0000000102e2d648
0x102e2d648: 0x00000001f65e60b0 0x00000001f65e60b0
0x102e2d658: 0x00070002838e4c00 0x0003e03500000000
(lldb) po 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
NSObject
(lldb) p/x 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
(unsigned long long) $15 = 0x00000001f65e60b0
通过第二个HFPerson类我们继续探索发现他的isa指针指向的是NSObject,而我们看到$15的地址跟原来一样,也就是说到顶了。
这边的NSObject是NSObejct类吗?
(lldb) p/x [NSObject class]
(Class) $17 = 0x00000001f65e60d8 NSObject
咦,发现$17 跟$15地址并不一样,所以上面的NSObject并不是我们所熟知的NSObject类,我们跟他取了一个名字叫
而上面的$13 跟 前面的$11不一样,我们将$13的HFPerson称之
通过上面的示例我们是不是可以得出这样的结论
对象isa->类isa->元类isa->NSObject(根元类)
等等刚刚HFPerson 继承 NSObject,如果有其他类继承HFPerson,那会有影响吗,我们再来实际考察一下
@interface HFStudent : HFPerson
@end
@interface HFPerson : NSObject
@end
HFPerson *p = [HFPerson alloc];
HFStudent *s = [HFStudent alloc];
NSLog(@"%@---%p", p, p); 断点到这里
(lldb) x/4gx s
0x281366340: 0x000001a10488562d 0x0000000000000000
0x281366350: 0x0000000000000000 0x0000000000000000
(lldb) po 0x000001a10488562d & 0x0000000ffffffff8ULL
HFStudent (对象isa指针指向类,这个没错)
(lldb) p/x 0x000001a10488562d & 0x0000000ffffffff8ULL
(unsigned long long) $2 = 0x0000000104885628
(lldb) x/4gx 0x0000000104885628
0x104885628: 0x0000000104885600 0x0000000104885678
0x104885638: 0x00000001ae8bdb10 0x0000803900000000
(lldb) po 0x0000000104885600 & 0x0000000ffffffff8ULL
HFStudent (类的isa指针指向元类HFStudent)
(lldb) p/x 0x0000000104885600 & 0x0000000ffffffff8ULL
(unsigned long long) $4 = 0x0000000104885600
(lldb) x/4gx 0x0000000104885600
0x104885600: 0x00000001f65e60b0 0x0000000104885650
0x104885610: 0x00030002808703c0 0x0003e03500000000
(lldb) po 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
NSObject (元类的isa指针指向的是根元类)
(lldb) p/x 0x00000001f65e60b0 & 0x0000000ffffffff8ULL
(unsigned long long) $6 = 0x00000001f65e60b0
这样就应该足够证明上面那个结论了
用一张图表示
元类
我们知道类有继承关系,元类是否也有呢?
同样我们还是用一个例子来说明
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
object_getClass 获取的是对象的isa指向
Class tMetaClass = object_getClass(HFStudent.class);
NSLog(@"%@ meta - %p",tMetaClass,tMetaClass);
Class tsuperClass = class_getSuperclass(tMetaClass);
Class pMetaClass = object_getClass(HFPerson.class);
NSLog(@"%@ meta - %p",pMetaClass,pMetaClass);
NSLog(@"%@ - %p",tsuperClass,tsuperClass);
Class psuperClass = class_getSuperclass(tsuperClass);
Class nMetaClass = object_getClass(NSObject.class);
NSLog(@"%@ meta- %p",nMetaClass,nMetaClass);
NSLog(@"%@ - %p",psuperClass,psuperClass);
Class rsuperClass = class_getSuperclass(psuperClass);
NSLog(@"%@ - %p",rsuperClass,rsuperClass);
Class prsuperClass = class_getSuperclass(rsuperClass);
NSLog(@"%@ - %p",prsuperClass,prsuperClass);
2021-06-19 16:23:20.349082+0800 StoreKitDemo[86485:3135162] HFStudent meta - 0x1053e7698
2021-06-19 16:23:20.349244+0800 StoreKitDemo[86485:3135162] HFPerson meta - 0x1053e76e8
2021-06-19 16:23:20.349344+0800 StoreKitDemo[86485:3135162] HFPerson - 0x1053e76e8
2021-06-19 16:23:20.349440+0800 StoreKitDemo[86485:3135162] NSObject meta- 0x7fff89c111d8
2021-06-19 16:23:20.349540+0800 StoreKitDemo[86485:3135162] NSObject - 0x7fff89c111d8
2021-06-19 16:23:20.349626+0800 StoreKitDemo[86485:3135162] NSObject - 0x7fff89c11200
2021-06-19 16:23:20.349721+0800 StoreKitDemo[86485:3135162] (null) - 0x0
-
首先获取了HFStudent的元类tMetaClass,通过class_getSuperclass获取到tMetaClass的父类为tsuperClass(HFPerson元类),然后继续通过class_getSuperclass获取tsuperClass的父类psuperClass(NSObject 根元类),在继续通过class_getSuperclass获取psuperClass的父类为rsuperClass(也是NSObject,但是从地址上看并不是根元类,是NSObject 根类),继续class_getSuperclass获取rsuperClass的父类结果为nil
从结果可以看出元类也是有继承关系,从而得出下图结论
结合上面两个结论我们可以得出苹果之前给的一张isa和继承关系图