Andrew
Andrew

Reputation: 24846

NSObject inherited class crashes the application

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 ?

Upvotes: 1

Views: 165

Answers (3)

Cory Kilger
Cory Kilger

Reputation: 13044

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.

Upvotes: 1

zoul
zoul

Reputation: 104065

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

Upvotes: 2

Dave DeLong
Dave DeLong

Reputation: 243146

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];

Upvotes: 1

Related Questions