Runtime中具体的方法调用流程
- 首先,在相应操作的对象中的缓存方法列表中找调用的方法,如果找到,转向相应的实现并执行;
- 如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应的实现并执行;
- 如果没找到,去父类指针所指向的对象中执行1、2;
- 以此类推,如果一直到根类都没有找到,转向拦截调用,走消息转发机制;
- 如果没有重写拦截调用方法,程序报错;
拦截调用
在方法调用中说到了,如果没有找到方法就会转向拦截调用。
那么什么是拦截调用呢?
拦截调用就是,在找不到调用的方法程序崩溃之前,你有机会通过重写NSObject的四个方法来处理:
+ (BOOL)resolveClassMethod:(SEL)sel;
+ (BOOL)resolveInstanceMethod:(SEL)sel;
//后两个方法需要转发到其他的类处理
- (id)forwardingTargetForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;
拦截调用的整个流程即Objective-C的消息转发机制。其具体流程如下图:
[image:A6043816-2585-4477-BE08-5C38F761E7E6-417-00001981CC42BFC1/message_forwarding.png]
由上图可见,在一个函数找不到时,runtime提供了三种方式去补救:
- 调用resolveClassMethod:(SEL)sel给个机会让类添加这个实现这个函数
- 调用forwardingTargetForSelector:(SEL)aSelector让别的对象去执行这个函数
- 调用forwardInvocation:(NSInvocation *)anInvocation(函数执行器)灵活的将目标函数以其它形式执行
如果都不中,调用doesNotRecognizeSelector抛出异常
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。