【问题标题】:How to call a method of super.super?如何调用super.super的方法?
【发布时间】:2011-07-03 10:28:48
【问题描述】:

我想在不破坏继承链的情况下调用超类的超类方法。像这样的:

+(id) alloc 
{
    return [super.super alloc];
}

有没有办法做到这一点?

不要与superclass 方法提供的行为混淆,讨论here


UPD:

说说supersuperclass 的区别。

可以说,我们有 AClassSuperAClass。如下从他们的名字AClass继承SuperAClass。他们每个人都有一个方法的实现-(void) foo;

AClass 实现了一种以下类方法:

1.超类:

+(id) alloc {
    return [[self superclass] alloc];
}

2。超级:

+(id) alloc {
    return [super alloc];
}

现在,假设这两行代码:

AClass *AClassInstance = [AClass alloc];
[AClassInstance foo];

在第一种情况下(使用超类),SuperAClassfoo 方法将被调用。 对于第二种情况(使用super),会调用AClassfoo方法。

【问题讨论】:

  • #1:我相信您已经将示例的标题(1. super,2. superclass)与实际代码混为一谈。
  • #2:AClass AClassInstance = [AClass alloc]; 无效,因为 Objective-C 对象必须存在于堆上,因此在其声明中需要指针。
  • #3:你不能发送[AClassInstance foo],因为AClassInstance不是一个类,+foo是一个类方法。
  • #4:alloc 是一个类方法,因此+ (id)alloc
  • 您应该将solution 移到答案中(不在问题区域内)。(a) 很难找到/阅读,(b) 允许人们对解决方案进行投票。还有更多 StackOverflow 方式 :)

标签: objective-c cocoa cocoa-touch ios


【解决方案1】:

在您的特定示例中,+superclass 实际上是要走的路:

+ (id)someClassMethod {
    return [[[self superclass] superclass] someClassMethod];
}

因为它是一个类方法,因此self 指的是定义+someClassMethod 的类对象。

另一方面,在实例方法中事情变得有点复杂。一种解决方案是在 supersuper(祖父)类中获取指向方法实现的指针。例如:

- (id)someInstanceMethod {
    Class granny = [[self superclass] superclass];
    IMP grannyImp = class_getMethodImplementation(granny, _cmd);
    return grannyImp(self, _cmd);
}

与类方法示例类似,发送两次+superclass 以获得超超类。 IMP 是一个指向方法的指针,我们获得了一个指向与当前名称相同的方法(-someInstaceMethod)但指向超类中的实现的 IMP,然后调用它。请注意,如果方法参数和返回值与 id 不同,则需要对此进行调整。

【讨论】:

  • grannyImp 这个名字让我笑了。
  • 不幸的是,superclass case 不是我想要使用的。请考虑我的问题更新。
  • 感谢您提供出色的运行时提示,您的答案非常接近!问题终于解决了,看更新的问题。
  • 别忘了#include <objc/runtime.h>
  • 我试过这个,但在奶奶的方法调用中得到了 EXC_BAD ACCESS。我实际上并没有返回 grannyImp(self, _cmd),只是调用了它。这可能是问题所在?
【解决方案2】:

感谢Bavarious,他启发我让一些运行时工作人员参与进来。

简而言之,所需的假设线:

return [super.super alloc];

可以转化为这个“真实”的:

return method_getImplementation(class_getClassMethod([[self superclass] superclass], _cmd))([self class], _cmd);

为了比较清楚,可以展开如下:

Method grannyMethod = class_getClassMethod([[self superclass] superclass], _cmd);
IMP grannyImp = method_getImplementation(grannyMethod);
return grannyImp([self class], _cmd);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2014-11-13
    • 2021-12-21
    • 2015-05-17
    • 1970-01-01
    • 2021-12-31
    • 2013-03-18
    • 2013-12-25
    相关资源
    最近更新 更多