2012-06-17 101 views
3

我已經在這裏問了很多次關於我試圖製作的這個紅潤遊戲的問題。我正在研究一個基於文本的冒險遊戲。首先,我是用Java編寫的,因爲那正是我學習遊戲的目的所在。現在我試圖學習iOS開發,它需要Objective-C。在參加Lynda Essentials課程之後,我對目標c感到非常滿意(當然,以前的Java經驗也有幫助)。無論如何,我正在研究這個遊戲,而且我遇到了一個對客觀c來說非常獨特的問題。「預期類型」錯誤目標C

在Java中,當我有多個類時,他們只需要在同一個目錄中,以便我可以在其他類中使用它們。這在Objective-C中不是這樣的...如果我想在類B中使用類A,則必須導入頭文件。對於此遊戲,我有兩個自定義類,一個Location類和一個Exit類。 Location類需要知道退出它有什麼(因此,如果我想使用它們,我必須導入Exit.h),並且退出需要知道它連接到哪個位置(所以我必須導入Location.h)。看起來我不能這樣做,因爲有些稱爲Circular Referencing(或類似的東西)。但是,如果我不這樣做,那麼我會得到一個「預期類型」錯誤。所以我不知道該怎麼做。我將在下面顯示代碼。

Exit.h

#import <Foundation/Foundation.h> 
#import "Location.h" 

#define NORTH 0 
#define SOUTH 1 
#define EAST 2 
#define WEST 3 

@interface Exit : NSObject 

@property NSString * dirName; 
@property NSString * dirShortName; 
@property int direction; 
@property Location * connection; 
-(id)initWithConnection:(Location *) loc andDirection:(int) dir; 

@end 

Exit.m

#import "Exit.h" 

@implementation Exit 

@synthesize dirName; 
@synthesize dirShortName; 
@synthesize direction; 
@synthesize connection; 

-(id)initWithConnection:(Location *)loc andDirection:(int)dir { 
    self = [super init]; 
    if(self) { 
    direction = dir; 
    switch(direction) { 
     case 0: 
     dirName = @"North"; 
     dirShortName = @"N"; 
     break; 
     case 1: 
     dirName = @"South"; 
     dirShortName = @"S"; 
     break; 
     case 2: 
     dirName = @"East"; 
     dirShortName = @"E"; 
     break; 
     case 3: 
     dirName = @"West"; 
     dirShortName = @"W"; 
     break; 
    } 
    connection = loc; 
    } 
    return self; 
} 

@end 

Location.h

#import <Foundation/Foundation.h> 

@interface Location : NSObject 

@property NSString * title; 
@property NSString * desc; 
@property NSMutableDictionary * exits; 
@property BOOL final; 

-(id) initWithTitle:(NSString *) _title; 
-(id) initWithDescription:(NSString *) _desc; 
-(id) initWithTitle:(NSString *) _title andDescription:(NSString *) _desc; 
-(void) addExit:(Exit *) _exit; 

@end 

Location.m

#import "Location.h" 

@implementation Location 

@synthesize title; 
@synthesize desc; 
@synthesize exits; 
@synthesize final; 

-(void) addExit:(Exit *) _exit { 

    NSString * tmpName = [_exit dirName]; 
    NSString * tmpShortName = [_exit dirShortName]; 
    [exits setObject:tmpName forKey:tmpShortName]; 

} 

-(NSString *)description { 
    NSString * tmp = [[NSString alloc] initWithFormat:@"%@\n%@\n",self.title,self.desc]; 
    for(NSString * s in exits) { 
    [tmp stringByAppendingFormat:@"\n%@",s]; 
    } 
    return tmp; 
} 

// Initialization Methods 
-(id) init { 
    self = [super init]; 
    if(self) { 
    title = @""; 
    desc = @""; 
    } 
    return self; 
} 

-(id) initWithTitle:(NSString *) _title { 
    self = [super init]; 
    if(self) { 
    title = title; 
    desc = @""; 
    exits = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil]; 
    } 
    return self; 
} 

-(id) initWithDescription:(NSString *) _desc { 
    self = [super init]; 
    if(self) { 
    title = @""; 
    desc = desc; 
    exits = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil]; 
    } 
    return self; 
} 

-(id)initWithTitle:(NSString *) _title andDescription:(NSString *)_desc { 
    self = [super init]; 
    if(self) { 
    title = title; 
    desc = desc; 
    exits = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil]; 
    } 
    return self; 
} 

@end 

我真的很希望我不想做一些不可能的事情。我也希望我的代碼能夠被理解,並且我在這裏並沒有太多愚蠢的行爲;)感謝任何建議。

回答

5

編輯: 剛纔重讀,現在明白了更好的,你需要做@class Exit;定義在Location頭退出類,然後你可以在出口頭相同@class Location;爲了告訴編譯器的類定義。然後,如果你是引用在實現文件(.M)這些類,那麼你會導入Exit.h文件和文件Location.h分別

+0

DanZimm是正確的。對頭文件中的其他類使用@class forward定義,然後在實現文件中僅導入頭文件* *。 – Philip

+0

這太棒了!這是Lynda課程中沒有涉及到的問題,所以我在做錯了。我很高興你爲我解決了問題! :) – CaldwellYSR

4

拇指我已經開始效仿,這似乎與直覺相反的我在第一的規則是這樣的:

在你的頭文件,使用「前聲明」力強,只有兩種例外: 頭你正在擴展的類,以及你所遵守的協議的頭文件;並且只在.m文件中執行#import指令。

這應該解決循環引用錯誤;它是我的。

請參閱here,併爲「forward」做一個'查找'。

+0

它看起來像你的答案是一樣的DanZimm的,但我不明白一些術語這就是爲什麼我接受他而不是你的。 – CaldwellYSR

+0

感謝您的注意:-)乾杯! –