不管是类对象还是元类对象,类型都是 Class,class 和 mete-class 的底层都是 objc_class 结构体的指针。

typedef struct objc_class *Class;


不少网上文章都是复制粘贴错的, 如下

#if !OBJC2 在 2006 年 7 月 WWDC 中,Apple 发布了 “Objective-C 2.0”。2.0 有很多的语法改进、runtime 改进、垃圾回收机制(已废弃)、支持 64 等。

上面 “! OBJC2 ” 之间的代码是 Objective-C 2.0 之前 1.0 版本的东西。2.0 已经不支持了。

1.OBJC1 objc_class 结构(过时)

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;



  1. OBJC2 结构

objc_class 的真实定义实际的代码我们可以从 objc-runtime-new.h 中看到 (中间代码省略):

objc_object 的真实定义 详见 objc-private.h 文件

如上图, 关系也如旧版本一样, objc_class 继承于 objc_object

objc_object 中有一个 isa 指针,那么 objc_class 继承 objc_object,也就同样拥有一个 isa 指针

所有继承自 NSObject 的类实例化后的对象都会包含一个类型为 isa_t 的结构体。

  • super_class 指向当前类的父类
  • cache 用于缓存指针和 vtable,加速方法的调用
  • bits 就是存储类的方法、属性、遵循的协议等信息的地方
  1. class_rw_t

objc_class 中的 data 返回 class_rw_t 结构,此结构定义如下:

class_rw_t是通过 bits 调用 data 方法得来的,来到 data 方法内部实现。我们可以看到,data 函数内部仅仅对 bits 进行&FAST_DATA_MASK操作

而成员变量信息则是存储在class_ro_t内部中的,我们来到class_ro_t内查看。 class_rw_t 表示 read writeclass_ro_t 表示 read only

  1. 总结

一个类的内部结构如下,

  • superClass 指向当前类的父类
  • cache_t 提供消息传递过程当中的缓存方法查找 , 实质上是装满了 bucket_t 的一个 hash 表。因为散列表检索起来更快,
  • class_data_bits_t 类的基础信息,包含了类的方法列表,协议列表等。

method_t 是一个方法的封装, 里面包括了名称 (SEL), 返回值, 参数, 与函数体 (实现)

Reference

简悦 SimpRead