1.Runtime 是什么?
Runtime是用来动态创建类和对象,进行消息发送和转发的一套机制。
2.Runtime 的运行原理?
要提运行原理,先要解释一下类的结构。
每个类都包含:isa指针,指向了MetaClass。super_class 父类、ivars(成员变量)、cache(缓存)、协议列表和method_list(方法列表)等。
消息:
OC代码 [receiver message] 编译后成 [objc_msgSend(receiver,selector)]
// 除了编译成objc_msgSend 外还有 objc_msgSendSuper 用super调用方法直接去父类找 以及objc_msgSend_stret 和 objc_msgSendSuper_stret
当一条OC代码转化成消息,首先找到接受者receiver,在它的cache中找selector,如果没找到再到method_list中找,如果没找到会沿着isa指针往metaClass中找,如果在Class中没找到的话就会去superClass中找一直找到。如果找到的话,会把方法存到Cache中,下次运行的时候就不用一层层往上找了。如果在rootClass中都没找到的话。在消息报错之前会还有机会处理这条消息。
在消息报错之前,如果你重写了
+(Bool)resolveInstanceMethod:(SEL)sel 或者 +(Bool)resolveClassMethod:(SEL)sel
// 动态提供添加方法 一般会在里面调用class_addMethod 添加方法来处理消息。
那么可以在这个方法里面处理消息,如果没有处理则会给对象发送一条fowardInvocation消息
你可以在-(void)forwardInvocation:(NSInvocation *)anInvocation 中把消息给转发给能处理的对象。
NSInvocation 对象包含了原来的消息和传递的参数。
3.Runtime 能做什么?
遍历类,找私有成员变量、私有方法,给Category添加成员变量、对library进行一些操作等。具体的方法参:官方文档
有关 Method Swizzling。
Method Swizzling 简单来说就是修改了Method(包含SEL,IMP的结构体) 的 IMP(一个指执行方法的函数指针)。在消息传达时,根据receiver找到对应的Selector后,它会根据Selector对应的IMP然后去找到方法。而Method Swizzling 其实就是修改了Seletor对应的IMP。
你可以通过重写或者替换掉某些方法的IMP来实现特定的功能。
比如:
void method_exchangeImplementations (Method m1, Method m2)
// 交换两个Method 的IMP
更多的方法可以查看官方文档
有关Method Swizzling更详细的文章:http://nshipster.com/method-swizzling/
参考文档: