【问题标题】:iOS - Cannot use 'super' as a reference?iOS - 不能使用“超级”作为参考?
【发布时间】:2012-05-14 06:47:04
【问题描述】:

我正在尝试使用NSInvocation 从子类调用超类方法。涉及的代码比较简单,大致如下:

- (NSInvocation*) invocationWithSelector:(SEL)selector {
    NSInvocation* call = [[NSInvocation alloc] init];
    [call retainArguments];
    call.target = super;  //ERROR:  use of undeclared identifier 'super'

    call.selector = @selector(selector);

    return call;
}

这对我来说似乎有点奇怪,因为我一直认为 super 遵循与 self 几乎相同的规则(即它可以被视为对相关对象的直接引用并分配给变量,用作返回值等)。在实践中似乎并非如此。

无论如何,有什么简单的方法可以让我的NSInvocation 以超类实现为目标(我不能使用self 作为目标,因为子类覆盖了超类方法),还是我需要寻找其他的方法?

【问题讨论】:

  • self.superclass 有效吗? (只是在这里猜测......)

标签: objective-c cocoa-touch inheritance nsinvocation


【解决方案1】:

更多信息请参见What exactly is super in Objective-C?,但 super 实际上并不是一个对象。 Super 是编译器生成 obj-c 运行时调用(特别是 objc_msgSendSuper)的关键字。基本上,这就像在发送消息之前将您的类转换为它的超类。

编辑 所以如果你重写了你想要调用的方法,你将不得不编写另一个方法来直接调用[超级方法],并将你的调用设置为调用那个方法。运行时只会向对象发送消息,它们将在实现它们的继承链的最低成员处处理。

【讨论】:

  • 有趣,所以如果您的子类提供自己的目标方法实现,那么基本上您不能使用NSInvocationperformSelector... 间接调用超类方法?这似乎有点限制。
  • 是吗? C++ 或其他基于 C 的语言是否允许您这样做?我的意思是,如果您覆盖功能,则意味着您希望您的类上的行为与其父类的行为不同(或除了其父类的行为之外)。如果这不是正确的想法,那么我想我对 OOP 的理解存在根本缺陷。
  • 不,其他语言似乎不允许这样做(刚刚尝试使用 Java,同样的问题)。但是你用“除了它的父类”的评论达到了关键点。子类有能力显式调用重写方法的超类实现,它也应该这样做。正因为如此,我看不出为什么它不能使用NSInvocationperformSelector... 调用隐式地做同样的事情。简而言之,我认为对超类实现的调用需要显式/立即调用是没有意义的。
  • 我的意思是它在继续做其他事情之前调用[超级方法] ^^;。如果你想成为铁杆,你可以在运行时切换你的两个函数的实现(不要忘记将它们切换回来)通过方法调配。请参阅此页面:cocoawithlove.com/2008/03/supersequent-implementation.html 您可以交换子类和超类的实现,它们将被向后调用到您的想法(这就是为什么这是硬核和可怕的)并且您的调用将实际执行超类 IMP。
  • 但是,跟踪切换它们的时间似乎与跟踪何时显式调用 [super] 一样麻烦。
【解决方案2】:

superself 是同一个对象,所以直接使用

call.target = self;

它们之间的区别在于,您可以使用super 作为self 的消息接收者,以确保它调用超类的实现。

【讨论】:

  • 您的意思是输入“self”吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
  • 1970-01-01
  • 2021-09-15
相关资源
最近更新 更多