美文网首页
消息转发机制

消息转发机制

作者: fcf7850dd33e | 来源:发表于2020-09-17 17:20 被阅读0次

    RunTime:

    1、获取所有的属性列表、方法列表、协议列表

    2、方法交换

    3、方法拦截调用,容错处理

    4、动态添加方法,关联对象分类添加属性objc_setAssociatedObject

    消息查找与消息转发机制:

    1、从缓存方法列表中查找

    2、从方法列表中查找

    3、从父类指针所指对象中查找

    4、一直没找到,转向拦截调用, 重定向

    5、如果没有重写拦截调用的方法,程序报错

    +(BOOL)resolveClassMethod:(SEL)sel;

    +(BOOL)resolveInstanceMethod:(SEL)sel;

    //后两个方法需要转发到其他的类处理

    -(id)forwardingTargetForSelector:(SEL)aSelector;

    -(void)forwardInvocation:(NSInvocation *)anInvocation;

    -(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector  //方法签名

    调用resolveInstanceMethod:方法 (或 resolveClassMethod:)。允许用户在此时为该 Class 动态添加实现。如果有实现了,则调用并返回YES,那么重新开始objc_msgSend流程。这一次对象会响应这个选择器,一般是因为它已经调用过class_addMethod。如果仍没实现,继续下面的动作。

    调用forwardingTargetForSelector:方法,尝试找到一个能响应该消息的对象。如果获取到,则直接把消息转发给它,返回非 nil 对象。否则返回 nil ,继续下面的动作。注意,这里不要返回 self ,否则会形成死循环。

    调用methodSignatureForSelector:方法,尝试获得一个方法签名。如果获取不到,则直接调用doesNotRecognizeSelector抛出异常。如果能获取,则返回非nil:创建一个 NSlnvocation 并传给forwardInvocation:。

    调用forwardInvocation:方法,将第3步获取到的方法签名包装成 Invocation 传入,如何处理就在这里面了,并返回非nil。

    调用doesNotRecognizeSelector: ,默认的实现是抛出异常。如果第3步没能获得一个方法签名,执行该步骤。

    上面前4个方法均是模板方法,开发者可以override,由 runtime 来调用。最常见的实现消息转发:就是重写方法3和4,吞掉一个消息或者代理给其他对象都是没问题的

    也就是说_objc_msgForward在进行消息转发的过程中会涉及以下这几个方法:

    resolveInstanceMethod:方法 (或 resolveClassMethod:)。

    forwardingTargetForSelector:方法

    methodSignatureForSelector:方法

    forwardInvocation:方法

    doesNotRecognizeSelector: 方法

    相关文章

      网友评论

          本文标题:消息转发机制

          本文链接:https://www.haomeiwen.com/subject/uyahyctx.html