Runtime是什么,听起来很高大上,很高逼格的样子,其实看见名字就可以"望文生义"而知,就是因为"Objective-C"语言是一门运行时的动态语言,Runtime在实际运用中就是一系列的函数而已。
1.Objective-C的机制
Objective-C中".m”中的m也就是message也就是消息机制的象征,因此从消息机制说起。 Objective-C 中的方法调用,不是简单的方法调用,而是发送消息,也就是说,其实 [receiver message] 会被编译器转化为: objc_msgSend(receiver, selector)
例如:我们常写的init方法是这样的
```
- (instancetype)init{
if (self = [super init]) {
[self run];
}
return self;
}
- (void)run
{
NSLog(@"runrunrun");
}
```
然后会被编译器编译成
```
static instancetype _I_Class_init(Class * self, SEL _cmd) {
if (self = ((Class *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Class"))}, sel_registerName("init"))) {
((void (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("run"));
}
return self;
}
```
由此看出,init方法的原型是这样子的
```
OBJC_EXPORT void objc_msgSend(void /* id self, SEL op, ... */ )
```
该函数有两个参数,一个 id 类型,一个 SEL 类型
2.SEL
SEL的定义可以在objc/objc.h中找到,是长成酱紫的
```
typedef struct objc_selector *SEL;
```
其实它就是个映射到方法的C字符串,你可以用 Objective-C 编译器命令 @selector() 或者 Runtime 系统的 sel_registerName 函数来获得一个 SEL 类型的方法选择器。
3.id
与 SEL 一样,id 也可以在 objc/objc.h 中找到,它是一个结构体类型的指针,可以指向任何OC对象
```
typedef struct objc_object *id;
```
其中objc_object 结构体是酱紫的,这样就是OC对象,这个结构体只有一个成员变量 isa,对象可以通过 isa 指针找到其所属的类。isa 是一个 Class 类型的成员变量
```
struct objc_object { Class isa OBJC_ISA_AVAILABILITY;};
```
4.Class
class也是一个结构体类型的指针,定义如下
```
typedef struct objc_class *Class;
```
objc_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;
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;
```
我们通常说的类就长这样子:
·Class 也有一个 isa 指针,指向其所属的元类(meta).
·super_class:指向其超类.
·name:是类名.
·version:是类的版本信息.
·info:是类的详情.
·instance_size:是该类的实例对象的大小.
·ivars:指向该类的成员变量列表.
·methodLists:指向该类的实例方法列表,它将方法选择器和方法实现地址联系起来。methodLists 是指向 ·objc_method_list 指针的指针,也就是说可以动态修改 *methodLists 的值来添加成员方法,这也是 Category 实现的原理,同样解释了 Category 不能添加属性的原因.
·cache:Runtime 系统会把被调用的方法存到 cache 中(理论上讲一个方法如果被调用,那么它有可能今后还会被调用),下次查找的时候效率更高.
·protocols:指向该类的协议列表.
引用:部分参考自@戴尼玛,感谢分享
改天在写Runtime的关于方法和属性列表以及一些使用场景吧