Runtime

119 阅读1分钟

类与对象的数据结构

Class

typedef struct objc_class *Class;

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
    Class super_class                       OBJC2_UNAVAILABLE;  // 父类
    const char *name                        OBJC2_UNAVAILABLE;  // 类名
    long version                            OBJC2_UNAVAILABLE;  // 类的版本信息,默认为0
    long info                               OBJC2_UNAVAILABLE;  // 类信息,供运行期使用的一些位标识
    long instance_size                      OBJC2_UNAVAILABLE;  // 该类的实例变量大小
    struct objc_ivar_list *ivars            OBJC2_UNAVAILABLE;  // 该类的成员变量链表
    struct objc_method_list **methodLists   OBJC2_UNAVAILABLE;  // 方法定义的链表
    struct objc_cache *cache                OBJC2_UNAVAILABLE;  // 方法缓存
    struct objc_protocol_list *protocols    OBJC2_UNAVAILABLE;  // 协议链表
#endif
} OBJC2_UNAVAILABLE;
  1. isa:指向类对象或元类
  2. super_class:指向父类,根类的super_class为NULL
  3. cache:缓存最近使用的方法。每调用过一个方法后,这个方法就会被缓存到cache列表中。
  4. version:提供类的版本信息。在对象的序列化时会用到,可以识别出不同类定义版本中实例变量布局的改变。

对于cache,举例说明执行过程:

NSArray *array = [[NSArray alloc] init];
  1. [NSArray alloc]先被执行。因为NSArray没有+alloc方法,于是去父类NSObject中查找。
  2. 检测NSObject是否响应+alloc方法,发现响应,于是检测NSArray类,并根据其所需的内存空间大小开始分配内存空间,然后把isa指针指向NSArray类。同时,+alloc也被加进cache列表中。
  3. 接着,执行-init方法,如果NSArray响应该方法,则直接将其加入cache,如不响应,则去父类查找。
  4. 在后期的操作中,如果再以[[NSArray alloc] init]这种方式来创建数组,则会直接从cache中取出相应的方法,直接调用。