在子类中更改ivar的类(到派生类)

时间:2012-04-30 05:22:30

标签: objective-c ios inheritance subclass ivars

假设我有两个基类ContainerGizmo。类Container具有类Gizmo的实例变量。

现在我继承Container(称为SubContainer),我也是GizmoSubGizmo)的子类。在SubContainer的某些方法中,我需要向GizmoSubGizmo之外没有的属性发送消息。有没有办法在SubGizmo中覆盖ivar为SubContainer类,所以我可以发送这些消息?

现在,每当我需要使用这样的属性或方法时,我可以通过将继承的ivar转换为SubGizmo来使其工作。

这就是为什么我想要这样的行为:我已经有了一个可行的游戏,但是我添加的模式越多,维护就越难。如果我想更改/添加将在每种模式下运行的方法;我需要去三个不同的游戏 - 控制器对象并进行更改。

通过子类化,我想将主要的游戏机制保留在基类中,并为每个模式创建一个子类。这样,我在基类中进行的更改将反映每种模式。但是,每个控制器和游戏对象都有针对不同模式的新方法,并且它们彼此发送消息。这就是我的问题所在。

4 个答案:

答案 0 :(得分:2)

使用这样的方法引入类型安全和转换逻辑:

@interface SubContainer ()

- (SubGizmo *)subGizmo;
// setter is often unnecessary
- (void)setSubGizmo:(SubGizmo *)pSubGizmo;

@end

@implementation SubContainer

...

- (SubGizmo *)subGizmo
{
    Gizmo * ret = self.gizmo;
    // sanity check the type to ensure this is properly initialized,
    // or return nil if holding a Gizmo is valid in this context:
    assert([ret isKindOfClass:[SubGizmo class]]);
    return (SubGizmo *)ret;
}

- (void)setSubGizmo:(SubGizmo *)pSubGizmo
{
    self.gizmo = pSubGizmo;
}

- (void)addWater
{
  [self.subGizmo addWater];
}

@end
然而,渐弱的复杂性表明,类型的更多变化值得考虑。

答案 1 :(得分:1)

只需为您的ivar使用type id,您只需要包含正确的头文件以避免警告。

答案 2 :(得分:0)

最简单的方法是在Container中使用SubGizmo,而不是Gizmo。 : - )

但是,如果由于某种原因无法直接执行此操作,则可以在运行时修改SubContainer(寻找class_addIvarclass_addMethod,我可以在需要时给您一个示例),但这无助于避免Xcode的警告。

答案 3 :(得分:-2)

您可以使用ON通知向所有游戏控制器发送更新。