RunTime
简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制
。bash
RunTime
的2个重要特种ui
先来看下 Class 的定义:spa
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
复制代码
实际上Class就是 objc_class指针
在<objc/runtime.h>中,能够找到一个叫objc_class
的struct。咱们看一下这个struct的定义code
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;
//ivar列表,是一个objc_ivar_list类型的指针 表明实例变量
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
// method列表,是一个objc_method_list二级指针
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
//存储经常使用method,加快消息转发速度
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
//存储实现的protocols
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
复制代码
日常咱们定义了一个class以后,实际上它会被编译成一个这样的struct;咱们定义的变量、方法等,都存储在struct中。cdn
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
复制代码
当咱们建立了一个类的实例后,其实生成了一个这样的struct。它里面的的Class isa,能够在消息转发时寻找到对应的classblog
看一下 objc_class
中的 objc_method_list
定义内存
struct objc_method_list {
int method_count;
/* variable length structure */
struct objc_method method_list[1];
}
复制代码
objc_method_list
里面存储了一个 objc_method字符串
struct objc_method {
SEL method_name;
char *method_types;
IMP method_imp;
}
复制代码
这个objc_method就是咱们熟悉的method。能够看到method主要由方法名、function指针组成,将SEL
和IMP
作了一个映射get
typedef struct objc_selector *SEL;
复制代码
objc_selector
就是一个C字符串。所以,SEL其实就是一个字符串,能够理解成是对方法名的hash化
typedef void (*IMP)(void /* id, SEL, ... */ );
复制代码
IMP是方法的具体实现
当咱们调用某个方法时,实际上是向这个object发送一个“消息”,包含了方法名和参数。经过isa
找到objc_class
, 而后在objc_class
中遍历寻找对应的objc_method
,找到以后再调用IMP。 也就是说,方法名SEl
和真正的实现代码IMP
之间,是由objc_method
来绑定的,这样就实现了相对的动态化。
objc_msgSend
等方法,向object
发送消息;objc_object
的isa
找到其所在class;SEL
是否是要忽略的;好比ARC中会忽略retain等操做;SEL
;一旦找到,就执行SEL
对应的IMP
;methodLists
里找;superclass
里找,一直找到NSObject
;