[英]Changing the class of an ivar (to a derived class), in a subclass
假设我有两个基类, Container
和Gizmo
。 Class Container
有一个类Gizmo
的实例变量。
现在我SubContainer
Container
(调用SubContainer
),我也是子类Gizmo
( SubGizmo
)。 在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_addIvar
或class_addMethod
,我可以在需要时给出示例),但这无助于避免Xcode的警告。
您可以使用NSNotifications将更新发送到所有游戏控制器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.