ObjectClass
不管是类对象还是元类对象,类型都是 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;
- 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
就是存储类的方法、属性、遵循的协议等信息的地方
- 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 write,class_ro_t
表示 read only。
- 总结
一个类的内部结构如下,
- superClass 指向当前类的父类
- cache_t 提供消息传递过程当中的缓存方法查找 , 实质上是装满了 bucket_t 的一个 hash 表。因为散列表检索起来更快,
- class_data_bits_t 类的基础信息,包含了类的方法列表,协议列表等。
method_t 是一个方法的封装, 里面包括了名称 (SEL), 返回值, 参数, 与函数体 (实现)