objective-C运行时编程指南之转发和多继承(续)

转发和继承

尽管消息模拟继承,但NSObject类对这两个从不会迷惑。像respondsToSelector:和isKindOfClass:方法只能在继承层次中看到,不能在转发链中看到。例如,如果Warrior对象被问是否响应negotiate消息,

if ( [aWarrior respondsToSelector:@selector(negotiate)] )

    ...

答案是NO,即使它可以没有错误地接收negotiate消息并且响应它们,在某种意义上,通过转发它们给Diplomat。(参见图5-1)

在许多情况下,NO是正确地答案。但也可能不是。如果你使用转发来设置代理对象或者扩张类的功能,转发机制应该和继承一样是透明的。如果你希望你的对象像真正地继承了它们把消息转发给的那个对象的行为,你将需要重新实现respondsToSelector: 和isKindOfClass:方法来包含你的转发程序:

- (BOOL)respondsToSelector:(SEL)aSelector

{

    if ( [superrespondsToSelector:aSelector] )

        return YES;

    else {

        /* Here, test whether theaSelector message can     *

         * be forwarded to anotherobject and whether that  *

         * object can respond toit. Return YES if it can.  */

    }

    return NO;

}

除了respondsToSelector: 和isKindOfClass:之外,instancesRespondToSelector:方法应该也反射转发程序。如果协议被使用,conformsToProtocol:方法同样地应该被添加到列表中。类似地,如果一个对象转发任何它收到的远程消息,它应该有一个methodSignatureForSelector:方法的版本,这个方法可以返回最终响应转发的消息的方法的准确的描述;例如,如果一个对象能够转发消息给它的代理,你像下面一样实现methodSignatureForSelector:方法:

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector

{

    NSMethodSignature* signature =[super methodSignatureForSelector:selector];

    if (!signature) {

       signature = [surrogatemethodSignatureForSelector:selector];

    }

    return signature;

}

你可能考虑把转发程序放在自己的代码中并且让所有这些方法包括forwardInvocation:方法在内调用它。

备注:这是一种高级的技术,只适合没有其他解决方法的情况。它的目的不是用来替代多继承的。如果你必须使用这种技术,确保你完全地理解做转发的类的行为和要转发的类的行为。

在这部分中被提到的方法在Foundation框架索引NSObject类说明中有描述。更多的关于invokeWithTarget:方法的信息,参见Foundation框架索引NSInvocation类说明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值