如何调用祖父母方法

时间:2010-09-13 14:58:20

标签: iphone objective-c

我需要打电话给我班上的祖父母方法。

@class Grandparent
+--->@class Parent   
     +---->@class Child

每个类都实现一个方法:

-(void)foo

如果我想从子类调用父方法foo,请使用:

[super foo]

如果我想打电话给祖父母的foo,我该怎么办? 无法拨打电话

[super [super foo]]

Ant的想法?

5 个答案:

答案 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,您需要阅读有关SELIMP类型以及如何调用的部分通过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));
}