OC isa走势图

OC底层原理学习

上一章我们得知isa存储了类型信息,用isa的地址 & ISA_MASK 就可以得到类的信息,这一章深入探索一下isa的走势图

ISA_MASK = 0x0000000ffffffff8ULL
p/x:以16进制读取对象的地址
x/4gx:以16进制形式读取4个8位的内存空间里面存储的值
p/t:将内存转为2进制
Person * person = [[Person alloc]init];
person初始化后,添加断点

  1. 获取person的内存地址
(lldb) p/x person
(Person *) $0 = 0x0000000101a04120
  1. 得到personisa指针地址,打印person的类信息
(lldb) x/4gx $0
0x101a04120: 0x001d8001000021d1 0x0000000000000000
0x101a04130: 0x0000000000000000 0x0000000000000000
(lldb) p/x 0x001d8001000021d1 & 0x0000000ffffffff8ULL
(unsigned long long) $1 = 0x00000001000021d0
(lldb) po $1
Person
  1. 得到了Person(类)的信息后,既然万物皆对象,让我们猜测一下,它是否有isa指针,如果有指向谁呢?
(lldb) x/4gx $1
0x1000021d0: 0x00000001000021a8 0x0000000100333140
0x1000021e0: 0x0000000101a04180 0x0001801000000003
(lldb) p/x 0x00000001000021a8 & 0x0000000ffffffff8ULL
(unsigned long long) $2 = 0x00000001000021a8
(lldb) po $2
Person
  1. 又得到了个Person(元类),也就是面试总提到的元类元类isa指向谁呢?继续打印
(lldb) x/4gx $2
0x1000021a8: 0x00000001003330f0 0x00000001003330f0
0x1000021b8: 0x000000010067a7b0 0x0003e03100000007
(lldb) p/x 0x00000001003330f0 & 0x0000000ffffffff8ULL
(unsigned long long) $3 = 0x00000001003330f0
(lldb) po $3
NSObject
  1. 我们找到了NSobject(根元类)根元类isa指向谁呢?继续打印
(lldb) x/4gx $3
0x1003330f0: 0x00000001003330f0 0x0000000100333140
0x100333100: 0x0000000100708e70 0x0004e03100000007
  1. 根元类isa地址跟根元类的地址是一样的,那是不是随便一个继承于NSObject的类都各自有各自的根源类呢?我们打印一下Person的父类,也就是NSObject根元类
(lldb) p NSObject.class
(Class) $5 = NSObject
(lldb) p/x NSObject.class
(Class) $6 = 0x0000000100333140 NSObject
(lldb) x/4gx $6
0x100333140: 0x00000001003330f0 0x0000000000000000
0x100333150: 0x000000010067ab70 0x0001801000000003
  1. 0x00000001003330f0这个地址又出现了,也就是说根元类只有一个

此时,我们已经可以得到一个初步的isa走位图

我们可以尝试再创建一个类继承于Person,然后观察走势图,就可以得到网络上比较经典的isa走位图了,偷个懒

isa走位图

Root class(class) 其实就是NSObject,NSObject 是没有超类的,所以Root class(class)superclass 指向nil
每个Class都有一个isa指针指向唯一的Meta class
Root class(meta)superclass指向Root class(class),也就是NSObject,形成一个回路
每个Meta classisa指针都指向Root class(metal)

你可能感兴趣的:(OC isa走势图)