[英]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.