1.objc_msgSend函数
在 Objective-C 中,消息是直到运行的时候才和方法实现绑定的。
我们调用方法的方式是 [reciver message], 会被编译器转化为转换成一个对消息函数objc_msgSend的调用。该函数有两个主要参数:消息接收者和消息对应的方法名字:
id objc_msgSend (receive, selector,... );
该消息函数做了动态绑定所需要的一切:
- 它首先找到选标所对应的方法实现。因为不同的类对同一方法可能会有不同的实现,所以找到的 方法实现依赖于消息接收者的类型。
- 然后将消息接收者对象(指向消息接收者对象的指针)以及方法中指定的参数传给找到的方法实 现。
- 最后,将方法实现的返回值作为该函数的返回值返回。
1.消息发送(send):
通过isa指针找到类,在类的缓存中查找方法的imp,如果没找到,就去类的方法列表查找,还没找到,就去父类中查找。
2.动态方法解析(resolve):
如果一直找到nsobject,还是没有找到方法的imp。就会开始尝试:
resolveMethod
此时,可以动态的给选择子添加方法的实现。
3. 消息转发(Message Forwarding):
如果resolve还是没有获得消息的imp。进入消息转发阶段。 首先会调用:
(id)forwardingTargetForSelector:(SEL)aSelector
把消息的接受者换成一个可以处理该消息的对象。此方法是指定备援接受者。但是消息的选择子和参数不变。
如果上一步还是不行,那么崩溃之前,系统会做一次完整的消息转发即:
(void)forwardInvocation:(NSInvocation *)anInvocation;
// Runtime系统会向对象发送methodSignatureForSelector:消息,并取到返回的方法签名用于生成NSInvocation对象。 但是我们如果用到这个方法,一般是不会简单的用原来的选择子和参数生成的anInvocation,而是自己做一个invocation,然后选择一个target。
网友评论