views:

39

answers:

3

Hi all! I'm new in objective-C and here is my problem: I want to write a game and i want to use a GameStateManager class to manage the game states. As i've read every class in Objective-C should be inherited from NSObject or it's subclass. So here is the GameStateManager interface:

@interface GameStateManager : NSObject {
    int currentState_;
}
+(id) instance;
-(void) setState:(int)state;

@end

And here is the implementation:

@implementation GameStateManager
+(id) instance
{
    GameStateManager *manager = [GameStateManager init];
return manager;
}

- (id) init
{
self = [super init];
return self;
}

- (void) setState: (int) state
{
switch (state)
{
    case GS_MAIN_MENU_START:
    {
//          MenuScene *menuScene = [MenuScene node];
//          [menuScene build: false];
        MenuScene *scene = [scene instance:self :false];
        [[CCDirector sharedDirector] runWithScene: scene];  
    }
        break;

    case GS_PLAYING:
    {

    }
        break;
}
}

@end

I use this class here:

gameStateManager = [GameStateManager instance];
[gameStateManager setState: GS_MAIN_MENU_START];

The second line generated an SIGABRT signal. What's the problem ?

+1  A: 
GameStateManager *manager = [GameStateManager init];

-(id)init is an instance method, not a class method. That line should look like this:

GameStateManager *manager = [[GameStateManager alloc] init];
Dave DeLong
Hm, that's a memory leak unless you declare `manager` to be static, and check to see if it's already created before calling `+alloc`.
jlehr
+2  A: 

The problem is here:

+ (id) instance
{
    GameStateManager *manager = [GameStateManager init];
    return manager;
}

In effect you are calling init without ever calling alloc. I’d recommend that you forget about the instance stuff and use the official init patterns until you are really comfortable with the memory management:

- (id) init
{
    self = [super init];
    if (self == nil)
        return nil;
    …
    return self;
}

…and then get your instance by calling [[GameStateManager alloc] init].

zoul
+1  A: 

The issue is that the gameStateManager isn't being created properly. Instead of

[GameStateManager init]

use

[[[GameStateManager alloc] init] autorelease]

The autorelease is for good memory management and doesn't actually affect the initialization.

Cory Kilger
You're answer seems to suggest that the *autorelease* is needed for what he tries to achieve. I know that's not what you wanted to say, but it just looks like this.
Georg
I realized that, and that's why I explicitly said it it's just for good memory management. But thanks for formatting that better for me, I was on an iPad. StackOverflow wasn't really made for iPads.
Cory Kilger