iOS总结-Runtime篇之类的消息传递

消息传递的核心机制就是objc_msgSend

id objc_msgSend(receiver self, selector _cmd, arg1,arg2,...)

self和_cmd是隐藏参数,编译器插入,self指向消息的接受者  _cmd是SEL类型

当向一般对象发送消息时,调用objc_msgSend,当向super发送消息时,调用objc_msgSendSuper,向结构体发送消息时,objc_msgSend_stret,objc_msgSendSuper_stret.

检查target是否是nil,如果是nil,直接cleanup,然后return,这也是我们可以向nil发送消息的原因.如果target为非nil,在target的Class中根据selector找寻IMP.

 找寻IMP:首先在target类的方法缓存列表里检查有没有对应方法实现,有直接调用,比较请求的selector和类方法/父类/根类的方法列表,找到了直接调用.(方法重写拦截父类方法的调用),然后调用方法实现,并将接受者和方法参数传给它,最后将实现函数的返回值作为自己的返回值.

如果上面都没有找到对应的selector,将会依次执行下面流程:

动态方法解析:+ (BOOL)resolveInstanceMethod:(SEL)sel里面调用class_addMethod方法

如果还没有找到,接着调用备用接受者:- (id)forwardingTargetForSelector:(SEL)aSelector

还没找到,接着进行一次完整的转发,首先进行方法签名调用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector,生成NSInvocation对象,执行forwardInvocation:(NSInvocation *)anInvocation,这一步比较耗时

如果以上三步还是没有响应,则调用doesNotRecognizeSelector:方法,抛出异常

unrecognized selector sent to instance 

猜你喜欢

转载自blog.csdn.net/qq_28551705/article/details/82971930