消息转发机制分为三步:
一、动态方法解析
二、快速消息转发
三、标准消息转发(normal forwarding)
参考文章:https://blog.csdn.net/qq_31586759/article/details/95081089
一、动态方法解析
1.执行方法调用代码(实例对象调用实例方法,类对象调用类方法)
Person *person = [[Person alloc] init];
[person eat];
2.查询对象中是否存在对应方法的IMP指针(实例方法在类里面找,类方法在父类中找)
3.如果存在,则直接执行IMP
指针对应的方法,方法调用结束。如果不存在,则执行4
4.判断该调用对象有没有实现resolveInstanceMethod:
(调用实例方法时)或者resolveClassMethod:
(调用类方法时)进行动态方法添加、交换,如果有,返回YES
,执行动态添加、交换的方法。如果没有,则调用[super resolveInstanceMethod:]
或者[super resolveClassMethod:]
,返回NO
时则继续执行5
二、快速消息转发
5.当IMP
指针不存在时,寻找是否在其他对象类有该方法实现,并将该消息转发给这个对象的forwardingTargetForSelector:
方法,如果目标对象实现了该方法,runtime
这时就会调用这个方法,给你把这个消息转发给其他对象的机会.只要这个方法返回的不是nil
和self
,整个消息发送的过程就会被重启,当然返回的对象会变成return的对象,否则就会继续标准消息转发(normal forwarding)
三、标准消息转发(normal forwarding)
这一步是消息转发机制中最后一道屏障,,首先会发送- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
消息获得函数的参数和返回值,如果返回nil
,runtime
则会发出doesNotRecognizeSelector:
消息,然后crash
,若是返回了一个函数签名,runtime
就会创建一个NSInvocation
对象并发送- (void)forwardInvocation:(NSInvocation *)Invocation
消息给目标对象。