美文网首页
OC-Runtime消息转发

OC-Runtime消息转发

作者: rookieme | 来源:发表于2018-12-06 11:35 被阅读0次

    Runtime 是 Objective-C 区别于 C 语言这样的静态语言的一个非常重要的特性。对于 C 语言,函数的调用会在编译期就已经决定好,在编译完成后直接顺序执行。但是 OC 是一门动态语言,函数调用变成了消息发送,在编译期不能知道要调用哪个函数。所以 Runtime 无非就是去解决如何在运行时期找到调用方法这样的问题。

    消息发送

    消息发送

    消息转发

    当向一个对象发送一条消息,但它并没有实现的时候,_objc_msgForward会尝试做消息转发

    image

    简单打印下消息转发的log(Xcode 10及以上未出现打印)

    首先随便创建个类(RuntimeTest 继承与NSObject,未实现test方法),编写一下代码

    RuntimeTest *test = [[RuntimeTest alloc] init];
    [test performSelector:@selector(test)];
    

    开启debug模式,在下面👇这句加断点,设备选择模拟器

    RuntimeTest *test = [[RuntimeTest alloc] init];
    

    运行代码,当执行到断点暂停时在lldb中输入

    po (void)instrumentObjcMessageSends(YES)
    

    继续执行代码直至崩溃,使用终端 open /private/tmp/ 打开文件夹找到msgSends-xxxx(最新时间生成)文件,(👇文件部分内容)

    - NSObject NSObject performSelector:
    + NSObject NSObject resolveInstanceMethod:
    + NSObject NSObject resolveInstanceMethod:
    - NSObject NSObject forwardingTargetForSelector:
    - NSObject NSObject forwardingTargetForSelector:
    - NSObject NSObject methodSignatureForSelector:
    - NSObject NSObject methodSignatureForSelector:
    - NSObject NSObject class
    - NSObject NSObject doesNotRecognizeSelector:
    - NSObject NSObject doesNotRecognizeSelector:
    - NSObject NSObject class
    

    结合NSObject文档,可以知道_objc_msgForward消息转发做了如下几件事:

    1. 通过resolveInstanceMethod得知方法是否为动态添加,YES则通过class_addMethod动态添加方法,处理消息,否则进入下一步。dynamic属性就与这个过程有关,当一个属性声明为 dynamic时 就是告诉编译器:开发者一定会添加setter/getter的实现,而编译时不用自动生成。

    2. 这步会进入forwardingTargetForSelector用于指定哪个对象来响应消息。如果返回nil则进入第三步。这种方式把消息原封不动地转发给目标对象,有着比较高的效率。如果不能自己的类里面找到替代方法,可以重载这个方法,然后把消息转给其他的对象。

    3. 这步调用methodSignatureForSelector进行方法签名,这可以将函数的参数类型和返回值封装。如果返回nil说明消息无法处理并报错unrecognized selector sent to instance,如果返回methodSignature,则进入forwardInvocation,在这里可以修改实现方法,修改响应对象等,如果方法调用成功,则结束。如果依然不能正确响应消息,则报错unrecognized selector sent to instance.

    使用场景:

    • 可以在消息转发过程中,利用第3步forwardInvocation使用try进行异常捕捉不抛出,从而避免一些崩溃
    • 可以利用 2、3 中的步骤实现对接受消息对象的转移,可以实现“多重继承”的效果。
    • 等等...

    博客链接:博客链接

    相关文章

      网友评论

          本文标题:OC-Runtime消息转发

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