美文网首页
ios消息转发机制

ios消息转发机制

作者: 学习的途中 | 来源:发表于2020-09-07 10:00 被阅读0次

        Objective-C是使用传递消息的机制来调用函数,这就会使用到动态绑定的机制在运行期来决定到底调用哪个方法,甚至我们可以在运行时改变对象调用的方法。

        关于对象发送消息,首先在该类的struct objc_method_list列表中去搜索,如果找到则直接调用相关方法的实现,如果没有找到就会通过super_class指针沿着继承树向上去搜索,如果找到就跳转,如果到了继承树的根部(通常为NSObject)还没有找到。那就会调用NSObjec的一个方法doesNotRecognizeSelector:,这样就会报unrecognized selector 错误。其实在调用doesNotRecognizeSelector:方法之前还会进行消息转发---还有三次机会来补救。也就是常说的OC消息转发的三次补救措施。

    总的来说一个OC消息的发送会经历四个阶段(该四个阶段都是搜索到NSObject再进入下阶段)

    1.先在本类中搜索改方法的实现,如果有则直接调用若果没有则去父类中搜索直到NSObject,如果NSObject没有则进入消息转发(类的动态方法解析、备用接受者、完整的消息转发)。

    2.类的动态方法解析:

        首先我们创建一个类ViewController;定义一个方法,但是不实现,这时候直接调用,程序会报错,直接crash,这时候如果我们实现了+ (BOOL)resolveInstanceMethod:(SEL)sel方法,并在里面实现动态方法的绑定,我们就可以正常的调用了,如图所示

    1

    可以看到虽然没有实现textAction:这个函数,但是我们通过class_addMethod动态添加dynamicMethodIMP函数,并执行dynamicMethodIMP这个函数的IMP。

    3.消息的重新定位(备用接受者)

        当我们 没有 通过class_addMethod动态添加dynamicMethodIMP函数,并执行dynamicMethodIMP这个函数的IMP,就可以重新定位消息的接受者。如果目标对象实现了-forwardingTargetForSelector:,Runtime 这时就会调用这个方法,给你把这个消息转发给其他对象的机会。如图

    2

    这时候我们重新创建了一个text1_VC,并在.h里声明了textAction,在.m里实现了textAction方法。可以看到我们通过forwardingTargetForSelector把当前ViewController的方法转发给了text1_VC去执行了

    4.完整的消息转发机制

    如果在上一步还不能处理未知消息,则唯一能做的就是启用完整的消息转发机制了。首先它会发送-methodSignatureForSelector:消息获得函数的参数和返回值类型。如果-methodSignatureForSelector:返回nil,Runtime则会发出-doesNotRecognizeSelector:消息,程序这时也就挂掉了。如果返回了一个函数签名,Runtime就会创建一个NSInvocation对象并发送-forwardInvocation:消息给目标对象。如图

    3

    从打印结果来看,我们实现了完整的转发。通过签名,Runtime生成了一个对象anInvocation,发送给了forwardInvocation,我们在forwardInvocation方法里面让text1_VC生成的对象去执行了textAction函数。

    相关文章

      网友评论

          本文标题:ios消息转发机制

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