小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
在之前的文章中我们知道了实例对象的isa指向类,类的isa指向它的元类,那么元类的isa又会指向谁呢? 为了探索,在main文件中写下如下简单代码:
LGPerson *p = [LGPerson alloc];
NSLog(@"%@",p);
可以得到实例对象的信息,就可以得到实例对象的isa
x/4gx p
--------------------
0x1005ad990: 0x011d800100008365 0x0000000000000000
0x1005ad9a0: 0x0000000000000000 0x0000000000000000
因为实例对象的isa指向类,对实例对象的isa进行& 0x00007ffffffffff8
操作,得到类的
地址,就可以获取到类信息
p/x 0x011d800100008365 & 0x00007ffffffffff8
--------------------------------------
0x0000000100008360
--------------------------------------
x/4gx 0x0000000100008360
0x100008360: 0x0000000100008338 0x00007fff807c2088
0x100008370: 0x000000010060f430 0x0001802c0000000f
---------
//通过类的isa进行& 0x00007ffffffffff8操作,获取元类的信息
p/x 0x0000000100008338 & 0x00007ffffffffff8
(long) $2 = 0x0000000100008338
打印元类的数据结构
x/4gx 0x0000000100008338**
0x100008338: 0x00007fff807c2060 0x00007fff807c2060
0x100008348: 0x000000010060eed0 0x0001e03500000003
- 元类
isa
:0x00007fff807c2060
元类isa
进行&
运算
p/x 0x00007fff807c2060 & 0x00007ffffffffff8
(long) $3 = 0x00007fff807c2060
- 得到相同的地址
将地址进行
po
打印
po 0x00007fff807c2060
NSObject
发现元类的isa
指向NSObject
查看NSObject
类的地址
p/x NSObject.class
(Class) $5 = 0x00007fff807c2088 NSObject
- 地址和
LGPerson
元类isa
指向的NSObject
地址不同 那么问题来了,元类的isa指向的地址到底是什么呢? 打印NSObject
类的数据结构
x/4gx 0x00007fff807c2088
------------------------------------
0x7fff807c2088: 0x00007fff807c2060 0x0000000000000000
0x7fff807c2098: 0x00000001005a7d00 0x0002801000000003
NSObject
作为根类,它的isa
指向的元类,称之为根元类- 根元类的地址和
LGPerson
元类isa
指向的地址相同 LGPerson
的元类isa
,指向的并不是NSObject
,而是根元类(NSObject
的元类) 打印根元类的数据结构
x/4gx 0x00007fff807c2060
----------------------------------
0x7fff807c2060: 0x00007fff807c2060 0x00007fff807c2088
0x7fff807c2070: 0x00000001005addc0 0x0003e03100000007
- 发现根元类的isa指向自己 由此,我们可以得出如下结论:
- 实例对象的isa指向类,类的isa指向元类,元类的isa指向根元类,而根元类的isa指向它自己(根元类)
- NSObject作为根类,isa走位只有两层
- 根类的isa指向根元类,根元类的isa指向它自己(根元类)
可参考苹果官方给出的isa走位图(虚线部分)