繁体   English   中英

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

[英]Changing the class of an ivar (to a derived class), in a subclass

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

现在我SubContainer Container (调用SubContainer ),我也是子类GizmoSubGizmo )。 SubContainer一些方法中,我需要向Gizmo没有的一些属性发送消息,但SubGizmo 有没有办法在SubContainer覆盖ivar为SubGizmo类,所以我可以发送这些消息?

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

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

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

只需使用如下方法介绍类型安全和转换逻辑:

@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

然而,爬行复杂性表明类型的更多变化值得考虑。

只需使用ivar的类型ID,您只需要包含正确的头文件以避免警告。

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

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

您可以使用NSNotifications将更新发送到所有游戏控制器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM