从objc源码看世界-isa走位及其在内存中的关系

181 阅读1分钟

isa走位

这个图在类的继承关系,元类中出现的频率非常高。可谓iOS神图之一。今天准备在换个角度看下类,元类,isa在内存中的关系。

#####准备工作 ######objc_class的结构

struct objc_class : objc_object {
    // Class ISA; // 8字节
    Class superclass;  //8字节
    cache_t cache;   //下面不在本篇讨论范围       
    class_data_bits_t bits;  
    ...
类关系
@interface FQSuperClass : NSObject
@end
@interface FQClass : FQClass
@end
FQClass -> FQSuperClass -> NSObject
objc_getMetaClass 和 object_getClass方法 ,到最后得到的ISA = isa.bits & ISA_MASK(省略其他步骤)
define ISA_MASK        0x00007ffffffffff8ULL // 这里是x86_64架构

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

inline Class 
objc_object::getIsa() 
{
    if (!isTaggedPointer()) return ISA();
    ... 暂时不考虑taggedPoint
}

Class objc_getMetaClass(const char *aClassName){
    return cls->ISA();
}

inline Class 
objc_object::ISA()  {
    return (Class)(isa.bits & ISA_MASK);
}

#####操作 接着我们分别申明3个上述对象在lldb中打印下。

依次打印,结合神图,我们得到最后的结果:
内存关系.png

这里我们从另一个侧面验证了一下类,元类,isa的关系,希望能够帮助大家更好理解上述之间的关系。

#####新发现 我们可以发现NSObject和NSObject元类和自定义的类和对应原来并不是存在在同一个内存区域。前者在栈中,测试了几个系统的类,发现也是在栈中。个人猜测是为了性能。这个问题mark一下,希望在后面阅读类的加载时能有所结论

#####为什么要设计元类?