iOS消息转发方法SignatureForSelector

Gen*_*ain 1 objective-c method-signature message-forwarding ios

因此,当我遇到一些稀缺资源时,我正在研究消息转发并运行一些单元测试,这些资源包括苹果公司自己的品牌文件,forwardInvocation:据我所知需要使用这些文件methodSignatureForSelector:

现在,我得到了一个大致的想法,methodSignatureForSelector:即查看您试图将消息转发到的对象是否具有匹配的方法名称和参数,以便可以调用forwardInvocation:我的问题,这是为什么为什么在apples文档中它说要调用methodSignatureForSelector:类似的超类的实现所以...

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
    NSMethodSignature* signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        signature = [surrogate methodSignatureForSelector:selector];
    }
    return signature;
}
Run Code Online (Sandbox Code Playgroud)

对我来说,这似乎是在说:“如果我继承的所有类都没有方法可以处理此方法,请检查替代对象是否具有此功能。”

苹果提供的例子是,在谈判方法上,战士代替外交官行事。在这个例子中,我看不出为什么要检查战士或父母中的任何一个是否有适当的方法签名来转发。因此,这使我相信存在另一个原因,这是我无法想到的,有人可以给我一个例子或帮助弄清楚我可能遗漏的地方吗?

TL; DR 为什么需要[super methodSignatureForSelector:selector];

Jos*_*fni 5

您是正确的-该示例尝试从超类获取方法签名,如果不能,则向代理请求一个。在整个“转发和继承”部分中,Apple会指导您如何使用消息转发-是否选择收听取决于您自己:)

为了全面说明,我将逐步浏览文档的主要部分:

  1. 尽管转发模仿继承,但NSObject类从不会混淆两者。诸如responsToSelector:和isKindOfClass:之类的方法仅查看继承层次结构,而不查看转发链。

实现消息转发不会立即影响respondsToSelectorisKindOfClass方法。如果转发negotiate给代理,则在继承层次结构中不存在该方法的情况下,如果调用[myWarrior respondsToSelector:negotiate]将返回NO

  1. 如果你使用的转发设置一个代理对象或扩展类的功能,转发机制应该大概是透明的继承。如果您希望您的对象像它们真正继承了将消息转发到的对象的行为一样工作,则需要重新实现responsesToSelector:和isKindOfClass:方法以包括您的转发算法。

关键字可能是-因此Apple为您提供建议。苹果公司表示,如果您希望YES在我的以上示例中返回myWarrior对象,因为您negotiate转到了代理对象,那么您需要覆盖该respondsToSelector方法。现在请注意,尽管negotiate您可以调用其他方法,但可能会在替代方法中调用您不希望返回的方法YES。例如,Diplomat类可能具有一个havePeaceCelebration方法。当向战士类发送此消息时,您可能尚未实现将消息转发到外交官类的步骤(因为战士没有进行和平庆祝活动),因此您将想返回NO

此外,父类可能具有chooseWeaponWarrior类中没有的方法。如果您打电话给[myWarrior respondsToSelector:chooseWeapon]您,那么您绝对肯定要检查超类是否响应,因为代理人(作为外交官)没有响应。

最后,父类和代理都有可能对选择器做出响应。苹果公司似乎建议父类赢得胜利-战士首先是战士,并且在某些情况下可以使用外交官,除非您强迫这样做。您最终如何实施它取决于您。

  1. 除了responsesToSelector:和isKindOfClass:外,instancesRespondToSelector:方法还应镜像转发算法。如果使用协议,则应该将conformsToProtocol:方法同样添加到列表中。同样,如果对象转发其收到的任何远程消息,则它具有methodSignatureForSelector版本:可以返回对最终响应所转发消息的方法的准确描述。例如,如果对象能够将消息转发到其代理,则可以实现methodSignatureForSelector:

关键字应该-再次推荐。这是您提供的代码之前的语句。这与的推理相同respondsToSelector,并且说对象应该是好公民。战士类可以处理一些远程消息,而其他消息则不能,而外交官类也可以。如果您选择始终将其转发给代理,则转发Warrior的超类可以处理的消息可能会造成混淆。或更糟糕的是,它可能转发Warrior的超类可以处理但代理不能处理的消息-可能导致异常。