2013-04-02 196 views
2

我遇到了一些實現簡單的超/子類方案的麻煩。我在超類中聲明瞭一個NSMutableDictionary,並試圖在子類中訪問它,但它只返回null。任何幫助,將不勝感激。從子類訪問超類屬性

@interface RootModel : NSObject <Updatable, TouchDelegate> 
@property (nonatomic) NSMutableDictionary *gameValues; 
@end 

@interface SubclassModel : RootModel 
@end 

@implementation RootModel 

- (id)initWithController:(id)controller { 
    if ((self = [super init])) { 
     _controller = controller; 

     _gameValues = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
         [NSNumber numberWithFloat:300.0f], KEY_JUMP_VELOCITY, 
         [NSNumber numberWithFloat:49.47f], KEY_GRAVITY, 
         [NSNumber numberWithFloat:0.25f], KEY_JUMP_TIME_LIMIT, 
         nil]; 

     NSLog(@"%@", _gameValues); 

    } 
    return self; 
} 

@implementation SubclassModel 

- (id)init{ 
    if ((self = [super init])) { 
     // This NSLog prints "(null)" if using super.gameValues or self.gameValues, why? 
     NSLog(@"subclass: %@", super.gameValues); 

    } 
    return self; 
} 
@end 

我在做什麼錯?

+0

請參閱此[post](http://stackoverflow.com/questions/5588799/objective-c-how-do-you-access-parent-properties-from-subclass)descrption和detail,將刪除從您的代碼的第一行NSObject。 –

回答

2

由於Catfish_Man回答,您init方法需要調用[super initWithController:]。然而,你似乎顯示了對你的評論的類/超類繼承模型的誤解:

我的超類由另一個控制器類初始化。任何對超級屬性(在initWithController中初始化:)的調用都是有效的(它們返回的值不爲空)。

當您創建SubclassModel的實例,那麼該實例有作爲的本身一個RootModel實例一部分。 RootModel實例是而不是SubclassModelRootModel的任何其他實例共享。

所以,如果「另一個控制器類」創建和初始化和RootModel,這反過來又顯示您NSLog輸出實例,那麼這是一個完全不同的對象,以你的SubclassModel實例 - 和RootModel這是你SubclassModel實例的一部分沒有初始化,因爲你不叫[super initWithController:],所以你NSLogSubclassModel顯示nil

+0

因此,擁有單例RootModel會更好,因此每個超類都不會啓動它自己的模型版本? – Clev3r

+0

@Clever - 不是。單身是一個不同的概念。當你聲明一個類「A」的子類,比如'B',那麼* B的每個*實例都有它自己的* A。這是繼承模式。如果你不確定這一點,你需要閱讀子類繼承的工作原理,這個模型是Obj-C(和大多數OO語言)的基礎,你需要理解它。 – CRD

+0

感謝您的提醒。顯然它太長了。但是,現在你已經澄清了這一點 - 我絕對不希望每個子類都擁有它自己的A. – Clev3r

1

您的子類init方法需要調用[super initWithController:],因爲這是實際初始化發生的地方。

(或initWithController:需要超打電話[self init],你需要你依靠的初始化工作移到init

+0

你確定嗎?我的超類由另一個控制器類初始化。任何對超級屬性(在'initWithController:'中初始化)的調用都是有效的(它們返回的值不爲空)。 – Clev3r

+0

根據發佈的代碼,是的,非常確定。在gameValues初始化的地方設置一個斷點,看它是否被擊中。除非你沒有包括的東西,否則它不會。 –

+0

想象一下其他一些類調用initWithController(它的作用)。設置一箇中斷點@ gameValues按預期行事......他們被分配並保存一個值。 – Clev3r