2011-10-25 46 views
0

我感興趣這篇文章讀來的StackOverflow: How to Make a Basic Finite State Machine in Objective-CObjective-C的狀態機傳遞參數

我就以此爲基礎建立我的狀態機進行簡單的足球比賽。我有狀態保衛,進攻,暫停,中立。我已經創建了狀態機,它將打印出NSLog「現在進入狀態保衛」等。

現在我想通過一個參考我的足球隊到狀態機,這樣我可以讓我的球隊根據國家做一些事情。也就是說,如果它的防守,我可以讓我的球員站在對手旁邊。

我試過很多不同的方法,但都以語法錯誤結束。 ID欣賞在正確的方向

推TeamState.h注意錯誤即時得到的意見

@class TeamState; 

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

@protocol TeamStateProt 

-(void) enterTeamState:(TeamState*)team; 
-(void) executeTeamState:(TeamState*)team; 
-(void) exitTeamState:(TeamState*)team; 

@end 


@interface TeamState : NSObject{ 
    id<TeamStateProt> currentTeamState; 

    id<TeamStateProt> Stoppage; 
    id<TeamStateProt> Neutral; 
    id<TeamStateProt> Defend; 
    id<TeamStateProt> Attack; 

    FootballTeam *footballTeam; //ERROR Unknown Type name FootballTeam 
} 

@property (nonatomic, retain) id<TeamStateProt> currentTeamState; 
@property (nonatomic, retain) id<TeamStateProt> Stoppage; 
@property (nonatomic, retain) id<TeamStateProt> Neutral; 
@property (nonatomic, retain) id<TeamStateProt> Defend; 
@property (nonatomic, retain) id<TeamStateProt> Attack; 

- (id)initWithFootBallTeam:(FootballTeam*) team; //Error Expected a Type 
-(void)update; 
-(void)changeState:(id<TeamStateProt>) newState; 
-(void)executeState:(id<TeamStateProt>) State; 
@end 

TeamState.m

#import "TeamState.h" 
#import "FootballTeam.h" 
#import "Stoppage_TS.h" 
#import "Neutral_TS.h" 
#import "Defend_TS.h" 
#import "Attack_TS.h" 


@implementation TeamState 

@synthesize currentTeamState; 
@synthesize Stoppage, Neutral, Defend, Attack; 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     // Initialization code here. 
     id<TeamStateProt> s = [[Stoppage_TS alloc] init]; 
     self.Stoppage = s; 

     id<TeamStateProt> n = [[Neutral_TS alloc] init]; 
     self.Neutral = n; 

     id<TeamStateProt> d = [[Defend_TS alloc] init]; 
     self.Defend = d; 

     id<TeamStateProt> a = [[Attack_TS alloc] init]; 
     self.Attack = a; 

     self.currentTeamState = n; 
     [self.currentTeamState enterTeamState:self]; 
     [self executeState:self.currentTeamState]; 
    } 

    return self; 
} 

- (id)initWithFootBallTeam:(FootballTeam*) team 
{ 
    self = [super init]; 
    if (self) { 
     // Initialization code here. 
     id<TeamStateProt> s = [[Stoppage_TS alloc] init]; 
     self.Stoppage = s; 


     id<TeamStateProt> n = [[Neutral_TS alloc] init]; 
     self.Neutral = n; 

     id<TeamStateProt> d = [[Defend_TS alloc] init]; 
     self.Defend = d; 

     id<TeamStateProt> a = [[Attack_TS alloc] init]; 
     self.Attack = a; 

     self.currentTeamState = n; 
     [self.currentTeamState enterTeamState:self]; 
     [self executeState:self.currentTeamState]; 

     footballTeam = team; 
    } 

    return self; 
} 

-(void)changeState:(id<TeamStateProt>) newState{ 
    NSLog(@"Changing State"); 
    if (newState != nil) { 
     NSLog(@"Changing a state which isn't nil"); 
     [self.currentTeamState exitTeamState:self]; 
     self.currentTeamState = newState; 
     [self.currentTeamState enterTeamState:self]; 
     [self executeState:self.currentTeamState]; 
    } 

} 

-(void)executeState:(id<TeamStateProt>) State{ 
    [self.currentTeamState executeTeamState:self]; 
} 

// Each update, execute the execute state on the current team state 
-(void)update{ 
    [self executeState:self.currentTeamState]; 
} 
@end 

FootballTeam.h

#import <Foundation/Foundation.h> 
#import "Player.h" 
#import "TeamState.h" 
#import "Football.h" 

typedef enum { 
    Home, 
    Away 
} TeamType; 

@interface FootballTeam : NSObject{ 
    Player *ReceivingPlayer; //Player to receive the ball 
    Player *ClosestToBall;  //Player closest to the ball 
    Player *ControllingPlayer; //Player who has the ball can be NULL 
    Player *SupportingPlayer; //Player in a position to receive the ball 

    NSMutableArray *players; //Array of all the Players on this team 

    TeamState *state;   //Current state of the teams state machine 

    TeamType type;    //Defines if Home team or Away team 
} 

@property (nonatomic) TeamType type; 
@property(nonatomic, retain) TeamState *state; 

-(void) sendPlayersToHome; 
-(Player*) playerClosestToBall:(Football*) ball; 
-(BOOL) areAllPlayersAtHome; 

@end 

回答

1

你有循環引用。你在FootballTeam.h中導入TeamState.h,反之亦然。

爲避免這種情況,只能將.h文件導入到.m文件中,並在.h文件中添加前向聲明。

所以,在TeamState.h:

@class FootballTeam; 

並移動進口TeamState.m

在FootballTeam一樣。

+1

爲了擴大這一點:#import是一個預處理器指令,與C的#include完全一樣,除了它自動忽略已經被#imported的文件。因此,當您導入FootballTeam.h時,它會導入TeamState.h,然後TeamState.h嘗試導入FootballTeam.h,但預處理器會因爲FootballTeam.h已導入而下降。正如Jrturton正確地指出的,正向聲明解決了這個問題,因爲它們提供了足夠的信息讓編譯器在不依賴導入的情況下繼續進行。 – Tommy

+0

完美竅門非常感謝您的幫助。 –