美文网首页
iOS面试题:_objc_msgForward 函数是做什么的,

iOS面试题:_objc_msgForward 函数是做什么的,

作者: sunnyxg0812 | 来源:发表于2020-02-13 23:38 被阅读0次

    我们可以这样创建一个_objc_msgForward对象:

    IMP msgForwardIMP = _objc_msgForward;

    _objc_msgForward是一个函数指针(和 IMP 类型一样),用于消息转发的:当向一个对象发送一条消息,但它并没有实现的时候,_objc_msgForward会尝试做消息转发。

    _objc_msgForward`消息转发做的几件事:

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

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

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

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

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

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

    注:

    直接调用_objc_msgForward是非常危险的事,如果用不好会直接导致程序Crash,但是如果用得好,能做很多非常酷的事。一旦调用_objc_msgForward,将跳过查找 IMP 的过程,直接触发“消息转发”,
    即使这个对象确实已经实现了这个方法,你也会告诉objc_msgSend:
    “我没有在这个对象里找到这个方法的实现”

    相关文章

      网友评论

          本文标题:iOS面试题:_objc_msgForward 函数是做什么的,

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