方法调用可以大致分为三个阶段:
消息发送阶段:从缓存中查找方法,如果找到即调用,没找到则进入动态解析阶段
动态解析阶段:负责动态添加方法实现,如果没有实现,则进入消息转发阶段
消息转发阶段:将消息转发给可以处理消息的对象
如果消息转发也没实现,就会包方法找不到错误:unrecognzied selector sent to instance
消息发送
1434508-b564f04069f7f53e.png动态解析
当本类包括父类cache包括class_rw_t中都找不到方法时,就会进入动态方法解析阶段;
动态解析对象方法时,会调用+(BOOL)resolveInstanceMethod:(SEL)sel方法。
动态解析类方法时,会调用+(BOOL)resolveClassMethod:(SEL)sel方法。
1434508-4a0b8a020a3307f7.png
消息转发
当本类没有实现方法,并且没有动态解析方法,就会调用forwardingTargetForSelector函数,进行消息转发,我们可以实现forwardingTargetForSelector函数,在其内部将消息转发给可以实现此方法的对象。
如果forwardingTargetForSelector函数返回为nil或者没有实现的话,就会调用methodSignatureForSelector方法,用来返回一个方法签名,这也是我们正确跳转方法的最后机会。
如果methodSignatureForSelector方法返回正确的方法签名就会调用forwardInvocation方法,forwardInvocation方法内提供一个NSInvocation类型的参数,NSInvocation封装了一个方法的调用,包括方法的调用者,方法名,以及方法的参数。在forwardInvocation函数内修改方法调用对象即可。
如果methodSignatureForSelector返回的为nil,就会来到doseNotRecognizeSelector:方法内部,程序crash提示无法识别选择器unrecognized selector sent to instance。
1434508-b3b8e9e574be80fa.png
网友评论