我想调用一个超类的超类方法,而不会破坏继承链。像这样:
+(id) alloc
{
return [super.super alloc];
}
有没有办法实现这个目标?
不要与superclass
方法提供的行为混淆,讨论here。
UPD:
关于super
和superclass
差异的几句话。
让我们说,我们有AClass
和SuperAClass
。如下所示AClass
继承SuperAClass
。他们每个人都有一个方法-(void) foo;
AClass
实现以下类方法之一:
1。超类:
+(id) alloc {
return [[self superclass] alloc];
}
2。超级:
+(id) alloc {
return [super alloc];
}
现在,假设这两行代码:
AClass *AClassInstance = [AClass alloc];
[AClassInstance foo];
在第一种情况下(使用超类),将调用SuperAClass
的{{1}}方法。
对于第二种情况(使用超级),将调用foo
的{{1}}方法。
答案 0 :(得分:35)
在您的特定示例中,+superclass
实际上是要走的路:
+ (id)someClassMethod {
return [[[self superclass] superclass] someClassMethod];
}
因为它是一个类方法,因此self
引用了正在定义+someClassMethod
的类对象。
另一方面,在实例方法中,事情变得更复杂。一种解决方案是获取指向超级(祖父)类中的方法实现的指针。例如:
- (id)someInstanceMethod {
Class granny = [[self superclass] superclass];
IMP grannyImp = class_getMethodImplementation(granny, _cmd);
return grannyImp(self, _cmd);
}
与类方法示例类似,+superclass
被发送两次以获取超级类。 IMP
是指向方法的指针,我们获取方法的IMP,其名称与当前方法(-someInstaceMethod
)相同,但指向超级类中的实现,然后调用它。请注意,如果存在方法参数并且返回值与id
不同,则需要进行调整。
答案 1 :(得分:3)
感谢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);