基础概念
SEL
SEL是方法选择器,即方法的ID。结构体如下,源码中没有objc_selector具体的定义。
但其实就是映射到方法的C字符串。不同类的同名方法具有相同的选择器,方法名相同单变量类型不同也会导致它们具有相同的选择器
1 | // An opaque type that represents a method selector. |
id
id
的结构体定义如下:
1 | typedef struct objc_object *id; |
1 | struct objc_object { |
objc_object
结构体包含一个isa_t
指针,isa_t
是一个联合体,根据isa
指针可以找到对象所属的类,isa
还涉及到 tagged pointer 的相关知识点。
Class
Class
是一个指向 objc_class
结构体的指针objc_class
继承自 objc_object
结构体,objc_class
的很多方法都基于它的几个成员实现的。
1 | typedef struct objc_class *Class; |
1 | struct objc_class : objc_object { |
为了处理类与对象的关系,Runtime创造了元类(Meta Class,类对象所属的类型就是元类,它用来表示类本身所具备的元数据。每个类只有一个类对象,每个类对象只对应一个元类
实例对象的isa
指针指向类对象的,类对象的isa
指针指向元类
根元类的isa
指针指向的是自己,而超类指向的NSObject
,NSObject
的超类的为nil
,也就是NSObject
没有超类
cache_t
cache_t
定义如下,方法缓存列表
1 | struct cache_t { |
buckets
是一个hask表,存储了调用过的方法体IMP。
1 |
|
cache
为方法调用进行了性能优化,每次方法调用了先从cache
中查找,命中就返回方法体IMP,否则再从isa
指向的方法列表遍历查找能够响应消息的方法
class_data_bits_t
class_data_bits_t
结构体定义如下
1 | struct class_data_bits_t { |
class_data_bits_t
包含了一个 bits
,这个指针跟不同的FAST_前缀的flag掩码做按位与操作,获取不同的数据
FAST_前缀的flag掩码
1 | // class is a Swift class |
bits
中其他的Fast_都是存储了相关标志位bool值,FAST_DATA_MASK 则存储了指向class_rw_t
的指针
1 | class_rw_t* data() { |
class_ro_t
objc_class
包含了 class_data_bits_t
, class_data_bits_t
存储了 class_rw_t
指针, class_rw_t
有包含了了 class_ro_t
class_ro_t
的结构体定义:
1 | struct class_ro_t { |
class_ro_t
中 method_list_t
、property_list_t
与property_list_t
都继承自entsize_list_tt
,protocol_list_t
存储了 protocol_ref_t
列表(也就是protocol_t
指针列表)。class_ro_t
存储的大多都是编译时信息就确定的信息
class_rw_t
class_rw_t
结构体定义
1 | struct class_rw_t { |
class_rw_t
提供了运行时类拓展的能力,而class_ro_t
存储的大多是编译时就确定的信息。虽然二者都包含了类的方法、属性以及协议等信息,但列表的实现方式不尽相同。class_rw_t
中的 method_array_t
、property_array_t
与protocol_array_t
都继承自list_array_tt
,list_array_tt
真正的为运行时提供了拓展能力,因为list_array_tt
可以存储list指针,内容有三种:
- 空
- entsize_list_tt指针
- entsize_list_tt指针数组
realizeClass
Category
Method
IMP
Ivar
objc_property_t
protocol_t
消息发送
objc_msgSend流程
- 检测这个
selector
是否要忽略 - 检测
target
是否为nil
- 从
cache
中查找对应的函数 cache
找不到,就从方法分发表中查找- 方法分发表中还找不到就到超类中查找,直到
NSObject
- 如果还找不到就进入动态方法解析
动态方法解析
消息转发
#健壮的实例变量 (Non Fragile ivars)