1:what is isa?
2:isa初始化 & isa <-> cls 关联
一个NSObject对象的第一个属性必然是isa。
isa <-> cls 关联
查看源码isa 的初始化:
inline void
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor)
{
assert(!isTaggedPointer());
if (!nonpointer) {
isa.cls = cls;//将cls与isa 关联上。
} else {
assert(!DisableNonpointerIsa);
assert(!cls->instancesRequireRawIsa());
isa_t newisa(0);
#if SUPPORT_INDEXED_ISA//0
assert(cls->classArrayIndex() > 0);
newisa.bits = ISA_INDEX_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
newisa.bits = ISA_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
//uintptr_t:unsigned long 偏移后的cls,将cls与isa 关联上。
newisa.shiftcls = (uintptr_t)cls >> 3;
#endif
isa = newisa;
}
}
发现isa与cls关联在了一起,验证关联:
sample:
LGTeacher *p = [LGTeacher alloc];
Class objct = object_getClass(p);
//lldb 打印 $4 与 $6值一样
(lldb) p/x LGTeacher.class
(Class) $4 = 0x0000000100001448 LGTeacher
(lldb) x/4xg p
0x101961ab0: 0x001d80010000144d 0x0000000000000000
0x101961ac0: 0x0000000000000000 0x0000000000000000
(lldb) p/x 0x001d80010000144d & 0x00007ffffffffff8
(long) $6 = 0x0000000100001448
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
inline Class
objc_object::getIsa()
{
if (!isTaggedPointer()) return ISA();
...
}
inline Class
objc_object::ISA()
{
assert(!isTaggedPointer());
#if SUPPORT_INDEXED_ISA
if (isa.nonpointer) {
uintptr_t slot = isa.indexcls;
return classForIndex((unsigned)slot);
}
return (Class)isa.bits;
#else
return (Class)(isa.bits & ISA_MASK);//# define ISA_MASK x86的 0x00007ffffffffff8ULL
#endif
}
3:isa & superClass 走位图

a sample:
LGPerson *object = [LGPerson alloc];//继承自NSObject
//1:检查实例对象内存
(lldb) x/4gx object
0x101120ba0: 0x001d800100001131 0x0000000000000000
0x101120bb0: 0x0000000000000002 0x00007fff9e64e898
(lldb) po 0x101120ba0
<LGPerson: 0x101120ba0>
// 0x001d800100001131 就是isa
// 通过 & ISA_MASK 运算可以得到 类对象 地址
//# define ISA_MASK 0x00007ffffffffff8ULL (x86下)
(lldb) p/x 0x001d800100001131 & 0x00007ffffffffff8ULL
(unsigned long long) $25 = 0x0000000100001130
(lldb) po 0x0000000100001130 得到类对象地址
LGPerson //实例对象的类对象为LGPerson
// 2:检查 类对象 内存
(lldb) x/4gx 0x0000000100001130
0x100001130: 0x001d800100001109 0x0000000100b35140
0x100001140: 0x0000000100f6df70 0x0000000400000007
//0x001d800100001109是类对象的isa ,此isa指向的是元类对象
(lldb) p/x 0x001d800100001109 & 0x00007ffffffffff8ULL
(unsigned long long) $31 = 0x0000000100001108 //得到元类对象地址
(lldb) po 0x0000000100001108
LGPerson conclusion:类对象isa 指向元类对象
//第二个0x0000000100b35140是 superclass (从这里看到了继承关系),实例对象第二个空间是空的
//只有isa 经过了 & ISA_MASK处理,superclass 存储的就是纯指针
(lldb) po 0x0000000100b35140
NSObject //得到父类
//3:查看元类对象地址0x0000000100001108
(lldb) x/4gx 0x0000000100001108
0x100001108: 0x001d800100b350f1 0x0000000100b350f0
0x100001118: 0x000000010122d320 0x0000000300000007
//这里的isa指向的是元类对象
(lldb) p/x 0x001d800100b350f1 & 0x00007ffffffffff8ULL
(unsigned long long) $34 = 0x0000000100b350f0
(lldb) po 0x0000000100b350f0
NSObject //conclusion:元类isa指向根元类对象
//第二个是 superclass
//元类的继承与类是差不多的,继承自根元类(Meta Root Class)
(lldb) po 0x0000000100b350f0
NSObject
//4:检查根元类对象地址0x0000000100b350f0
(lldb) x/4gx 0x0000000100b350f0
0x100b350f0: 0x001d800100b350f1 0x0000000100b35140
0x100b35100: 0x0000000100f6e320 0x0000000400000007
(lldb) p/x 0x001d800100b350f1 & 0x00007ffffffffff8ULL
(unsigned long long) $38 = 0x0000000100b350f0
(lldb) po 0x0000000100b350f0
NSObject //conclusion:这里根元类isa指向的是自己
//第二个是 superclass
//根据之前检查 0x0000000100b35140 是NSObject (基类)
(lldb) po 0x0000000100b35140
NSObject //conclusion :根元类 的superclas指向了基类,也就是继承自基类
至此以上sample验证isa走位图。