iOS Runtime
Runtime 简介:
Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的。
与Runtime交互
Objc 从三种不同的层级上与 Runtime 系统进行交互,分别是通过 Objective-C 源代码,通过 Foundation 框架的NSObject类定义的方法,通过对 runtime 函数的直接调用。
Runtime 是什么:
1.运行时(Runtime)是指将数据类型的确定由编译时推迟到了运行时。
2.Runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。
3.平时编写的OC代码,在程序运行过程中,其实最终会转换成Runtime的C语言代码,Runtime是Object-C的幕后工作者。
4.Object-C需要Runtime来创建类和对象,进行消息发送和转发。
特性: 编写的代码具有运行时、动态特性。
Runtime用来干什么?用在哪些地方?
用来干什么 基本作用
1.在程序运行过程中,动态的创建类,动态添加、修改这个类的属性和方法;
2.遍历一个类中所有的成员变量、属性、以及所有方法;
3.消息传递、转发;
4.方法调配;
5.“类对象” NSProxy;
6.KVC、KVO ;
用在哪些地方 Runtime的典型事例
1.给系统分类添加属性、方法;
2.方法交换;
3.获取对象的属性、私有属性;
4.字典转换模型;
5.KVC、KVO;
6.归档(编码、解码);
7.NSClassFromString class<->字符串
8.block;
9.类的自我检测;
10.Aspects(AOP必备,“取缔” baseVC,无侵入埋点)
消息转发机制
当向某个对象发送一条消息时,若该对象的方法列表以及它相应继承链上的方法列表都无法找到以该消息选择子作为key的方法实现时,则会触发消息转发机制。
1.动态方法解析 + (BOOL)resolveInstanceMethod:(SEL)sel;
当接受到未能识别的选择子时,运行时系统会调用该函数用以给对象一次机会来添加相应的方法实现,如果用户在该函数中动态添加了相应方法的实现,则跳转到方法的实现部分,并将该实现存入缓存中,以供下次调用。
2.备用接收者 - (id)forwardingTargetForSelector:(SEL)aSelector;
如果运行时在消息转发的动态方法解析中未找到所调用方法的实现,那么当前接收者还有第二次机会进行未知选择子的处理。这时运行期系统会调用上述方法,并将未知选择子作为参数传入,该方法可以返回一个能处理该选择子的对象,运行时系统会根据返回的对象进行查找,若找到则跳转到相应方法的实现,则消息转发结束。
3.完整的消息转发 - (void)forwardInvocation:(NSInvocation *)anInvocation;
当运行时系统检测到备援接收者中用户未返回能处理相应选择子的对象时,那么来到这一步就要启动完整的消息转发机制了。该方法可以改变消息调用目标,运行时系统根据所改变的调用目标,向调用目标方法列表中查询对应方法的实现并实现跳转,这种方式和备用接收者步的操作非常相似。当然你也可以修改方法的选择子,亦或者向所调用方法中追加一个参数等来跳转到相关方法的实现。
最后,如果消息转发的第3步还未能处理该未知选择子的话,那么最终会调用NSObject类的如下方法用以异常的抛出,表明该选择子最终未能处理。
- (void)doesNotRecognizeSelector:(SEL)aSelector;
附上完整的消息转发流程图: