前置文章: iOS底层之类的重要组成部分-isa结构体分析
前言
从上篇文章中我们得知对象的isa
指针中的shiftcls
存储的是类指针的值,那么这个值到底代表什么呢,接下来让我们探索一下。
一、isa指针探索
首先我们先用对象的isa指针 & ISA_MASK
得到如下结果:
WJPerson
,那么这个WJPerson
会不会是类的地址的,接下来我们打印下WJPerson
的类地址再来验证一下isa
的指针的shiftcls
的结果一模一样,而shiftcls
存储的又是类指针的值,所以我们可以得出结论:对象的isa指针指向的是类对象
。那么类对象的isa指针指向什么呢?我们再来实验一下
WJPerson
,但是这个WJPerson
和第一次打印的WJPerson
的指针不一样,怎么回事,难道OC
会创建两个一模一样的类吗?我们来测试下
void testClassPoint(){
Class class1 = [WJPerson class];
Class class2 = [WJPerson alloc].class;
Class class3 = object_getClass([WJPerson alloc]);
Class class4 = [WJPerson alloc].class;
NSLog(@"\n%p \n%p \n%p \n%p", class1, class2, class3, class4);
}
打印结果
0x100002140
0x100002140
0x100002140
0x100002140
从上述结果可知,OC
只会存在一个类。那么我们之前获取到的第二个WJPerson
是什么呢?
有的同学可能会知道在OC
中还有一个元类
的概念,元类
和类
有些相似,我们知道类
是使用存储对象
信息的,那么元类
就是存储类对象
信息的类。说了这么多,空口无凭,我们再来验证下
类对象的isa指针指向元类
。接下来我们再看下
元类
的isa
指针指向什么。NSObject
,那么这个NSObject
是到底是类
还是元类
,接下来我们打印下NSObject
的类
和元类
的地址alloc
重新创建一个对象获得的地址也一样。从图中我们发现WJPerson
的元类的isa指针指向的是NSObject
的元类。我们一般把NSObject
叫做根类
,那么NSObject
的元类就叫做根元类
。所以我们可以得出结论:元类的isa指针指向的是根元类
。我们在看下根元类的isa指向的是什么。
根元类的isa指针指向的是本身
,这样就形成了一个闭环。我们总结一下我们的验证结果
- 对象的isa指针指向的是类对象
- 类对象的isa指针指向元类
- 元类的isa指针指向的是根元类
- 根元类的isa指针指向的是本身