OC对象的三种分类(二)


问题:缓存

  1. 对象的isa指针指向哪里
  • 实例对象的isa指向类对象
  • 类对象的isa指向元类对象
  • 元类对象的isa指向基类的元类对象
  1. oc对象的信息存储在哪里?
  • 对象方法、属性、成员变量、协议存储在class对象中
  • 类方法存储在元类对象中
  • 成员变量的值存储在实例对象中

object-c中的对象主要分为3种:

  • instance对象(实例对象)
  • class对象(类对象)
  • meta-class对象(元类对象)

instance对象

  • instance对象就是经过类alloc出来的对象,每次调用alloc都会产生新的instance对象
  • 内存中存储着:
  • isa指针
  • 其余成员变量

class对象

  • 每一个类对象在内存中有且只有一个class对象
  • 内存中存储着:

  • isa指针
  • superclass指针
  • 类的属性信息(@property)、类的对象方法信息(instance > * method)
  • 类的协议信息(protocol)、类的成员变量信息(ivar)
  • 其余成员变量

meta-class对象

  • 即类对象的isa所指向的对象,每一个类在内存中有且只有一个meta-class对象
  • meta-class对象和class对象的内存结构是同样的,可是用途不同
  • 经过 object_getclass可获取到元类对象
  • 内存中存储着:

  • isa指针
  • superclass指针
  • 类的属性信息(@property)、类的对象方法信息(instance > * method)
  • 类的协议信息(protocol)、类的成员变量信息(ivar)
  • 其余成员变量

三种对象的isa和superclass指针之间的关系

  • isa指针

  • class对象的superclass指针

  • meta-class对象的superclass指针

  • 总结

class结构

从底层来看,class和meta-class都是objc_class结构markdown

struct objc_class  {
    Class ISA;
    Class superclass;
    cache_t cache;             // 方法缓存
    class_data_bits_t bits;    // 类的具体信息,想要&FAST_DATA_MASK才能获取到正确的地址
    ...
};
复制代码

class_data_bits_t结构大致:ui

struct class_data_bits_t {
    class_rw_t* data; //存储类的信息
    ...
}
复制代码

class_rw_t大致结构:atom

struct class_rw_t { 
    uint32_t flags;
    uint16_t witness;
    explicit_atomic<uintptr_t> ro_or_rw_ext;
    Class firstSubclass;
    Class nextSiblingClass;
    using ro_or_rw_ext_t = objc::PointerUnion<const class_ro_t *, class_rw_ext_t *>;
    const ro_or_rw_ext_t get_ro_or_rwe();
    const class_ro_t *ro();
    const method_array_t methods();         //方法列表
    const property_array_t properties();    //属性列表
    const protocol_array_t protocols();     //协议列表
    ...
};
复制代码

其中ro结构体为:spa

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;			 //实例建立出来的占用的空间大小
#ifdef __LP64__
    uint32_t reserved;
#endif
    const uint8_t * ivarLayout;
    const char * name;                //类名
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;
    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;
    ...
};
复制代码

小细节:define ISA_MASK 0x0000000ffffffff8ULL能够发现isa指向的类或者元类对象的地址,最后三位都是0。3d

相关文章
相关标签/搜索