我需要打电话给我班上的祖父母方法。
@class Grandparent
+--->@class Parent
+---->@class Child
每个类都实现一个方法:
-(void)foo
如果我想从子类调用父方法foo,请使用:
[super foo]
如果我想打电话给祖父母的foo,我该怎么办? 无法拨打电话
[super [super foo]]
Ant的想法?
答案 0 :(得分:6)
当然,您可以使用父类的 help 来实现此目的。如果您的foo
调用[super foo]
和您的超类然后调用[super foo]
,因为它会预期此行为,那么您已全部设置完毕。这是一种常见模式(例如-init
和-dealloc
)。
但是你不能直接使用普通的Obj-C语法跳转。每个子类都围绕其状态和方法为类定义自己的语义集。如果您可以在继承链的任何地方随意调用实现,而中间实现不了解它的任何内容,那么没有实现可以保证其自身状态的完整性,并且它会破坏类的抽象。
换句话说,我讨厌成为这样说的人,你应该重新考虑你的设计,如果这似乎是你真正想做的事情。 (如果是这样,请随意打开一个新问题来讨论对象模型的设计。这里的人们很乐意提供帮助。)
那就是说,从技术上讲,我怀疑你可以通过直接处理Obj-C运行时来实现这一点。你可以得到你的对象的类引用,然后是它的超类,然后是它的超类,并从中获得你想要的方法实现。然后用你的对象调用它。这个代码是读者的练习。 :) Here are the docs。
答案 1 :(得分:1)
如果你觉得你需要这样做,那可能是一个糟糕的设计。你应该根据quixoto的回答重新思考你正在做的事情。 quixoto提到了目标c运行时库,但是NSObject有实例和类方法来做这些事情。像quixoto一样,我会把它作为锻炼给你。要查看的方法有-(Class)class
,+(Class)superclass
,+(IMP)instanceMethodForSelector:SEL
,您需要阅读有关SEL
和IMP
类型以及如何调用的部分通过IMP
s。
如果你编写代码并且它看起来很糟糕(它会,不用担心),这可能是因为你不应该这样做。
答案 2 :(得分:0)
如果你真的想这样做(不完全确定为什么),你可以装配Parent来调用GrandParent([super foo])。然后当Child Foo调用Parent Foo时,它将调用GrandParent Foo。
可选地,您可以在调用[super foo]的父级上创建一个方法。
答案 3 :(得分:0)
当你在iPhone上时,你会看到这样的设计模式:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
如果你创建一个新的UIViewController子类。正如其他人所建议的那样,在子类中重载方法时应该遵循这种模式。
@implementation Grandparent
- (void) printSelf
{
NSLog(@"Grandparent");
}
@end
@implementation Parent
- (void) printSelf
{
[super printSelf];
NSLog(@"Parent");
}
@end
@implementation Child
- (void) printSelf
{
[super printSelf];
NSLog(@"Child");
}
@end
我认为您无法执行以下操作,因为方法调用是在运行时确定的,而不是在编译时确定的。这可能适用于Java或C ++,因为语言的绑定和分派规则。
@implementation Child
- (void) printSelf
{
[(Grandparent *)self printSelf]
}
@end
尝试一下,但我怀疑它会起作用。
答案 4 :(得分:0)
不确定为什么你想要这样的东西,因为它打破了OO设计,但它听起来很有趣。这是它的工作代码:
#import <objc/message.h>
...
- (void)foo {
struct objc_super x = {
self,
[[self superclass] superclass] // or any class compatible with self; repeat for more fun :)
};
objc_msgSendSuper(&x, @selector(foo));
}