美文网首页ios&&OC
Objective-C 的消息转发

Objective-C 的消息转发

作者: kindom_0129 | 来源:发表于2019-08-14 11:36 被阅读0次

    消息在OC中方法调用是一个消息发送的过程。OC方法最终被生成为C函数,并带有一些额外的参数(self 、_cmd)

    objc_msgSend(void /* id self, SEL op, ... */ )
    

    OC的方法本质


    • 在编译时你写的 OC 函数调用的语法都会被翻译成一个 C 的函数调用 objc_msgSend()
    [array insertObject:obj atIndex:5];
    //等价于
    objc_msgSend(array, @selector(insertObject:atIndex:), obj, 5);
    

    OC消息转发的步骤


    1.通过 \color{red}{recevier }\color{red}{isa}指针 找到 \color{red}{recevier}\color{red}{Class(类)}
    2.在 \color{red}{Class(类)}\color{red}{cache}(方法缓存) 的散列表中寻找对应的\color{red}{IMP}(方法实现);
    3.如果在\color{red}{cache}(方法缓存) 中没有找到对应的 \color{red}{IMP}(方法实现) 的话,就继续在\color{red}{Class(类)}\color{red}{method list}(方法列表) 中找对应的 \color{red}{selector},如果找到,填充到 \color{red}{cache}(方法缓存) 中,并返回 \color{red}{selector}
    4.如果在\color{red}{Class(类)} 中没有找到这个 \color{red}{selector},就继续在它的 \color{red}{superClass}(父类)中寻找;
    5.一旦找到对应的 \color{red}{selector},直接执行 \color{red}{recever}对应 \color{red}{selector} 方法实现的 \color{red}{IMP}(方法实现)。
    6.若找不到对应的 \color{red}{selector},要开始进入 \color{red}{动态方法解析和消息转发},消息被转发或者临时向 \color{red}{recever} 添加这个 \color{red}{selector} 对应的实现方法,否则就会发生崩溃。

    + (BOOL)resolveInstanceMethod:(SEL)sel;
    + (BOOL)resolveClassMethod:(SEL)sel;
    
    - (id)forwardingTargetForSelector:(SEL)aSelector;
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
    - (void)forwardInvocation:(NSInvocation *)anInvocation;
    
    • 动态方法解析和消息转发流程:


      图片来自网络

    OC 中给一个对象发送消息的完整步骤:


    1.在对象类的 dispatch_table 中尝试找到该消息。如果找到了,跳到相应的函数IMP去执行实现代码(参考OC消息转发的步骤);
    2.如果没有找到,运行时系统会发送+resolveInstanceMethod:或者 +resolveClassMethod:尝试去 resolve 这个消息;
    3.如果 resolve 方法返回NO,运行时系统就发送 -forwardingTargetForSelector: 允许你把这个消息转发给另一个对象;(resolve 方法返回YES时,运行时系统就会重新启动一次消息发送的过程)
    4.如果没有新的目标对象返回,运行时系统就会调用 -methodSignatureForSelector:和-forwardInvocation: 消息。你可以发送-invokeWithTarget:消息来手动转发消息或者发送 -doesNotRecognizeSelector:抛出异常;
    5.如果都没有,系统抛出异常。

    类方法的调用过程 和对象方法调用差不多,流程如下:


    1.通过类对象\color{red}{isa}指针 找到所属的\color{red}{Meta Class} (元类);
    2.在 \color{red}{Meta Class} (元类) 的\color{red}{method list}(方法列表) 中找到对应的 \color{red}{selector};
    执行对应的 \color{red}{selector}

    注意
    需要注意的是类方法的解析,动态增加方法时候,需要加到元类上,因为类方法列表是在元类对象中存储的。

    相关文章

      网友评论

        本文标题:Objective-C 的消息转发

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