Matt Caswell
Matt Caswell

Reputation: 43

App Crashes whenever empty method is called

so i was programming a game in Xcode 3.2.4 with cocos2d and i made a class named player. as of now it only has the one function that does nothing.

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

@interface Player : CCSprite {

}

-(void)leftButtonPressed;

@end 



#import "Player.h"


@implementation Player

- (id)init{
    if((self=[super init])){
        self = [CCSprite spriteWithFile:@"playerPlane.png"];
        }
    return self;
}

-(void)leftButtonPressed{
}

@end `

whenever i try to call leftButtonPressed from anywhere, the entire app crashes with this in the console

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CCSprite leftButtonPressed]: unrecognized selector sent to instance 0x6e4bb50'

i initialize the Player as an instance in another class by doing Player * thePlayer = [[Player alloc]init];

please help! thanks!!

Upvotes: 0

Views: 101

Answers (2)

Hermann Klecker
Hermann Klecker

Reputation: 14068

This causes the problem:

- (id)init{
    if((self=[super init])){
        self = [CCSprite spriteWithFile:@"playerPlane.png"];
        }
    return self;
}

What are you doing? You initialise the newly created (the caller that calls alloc/init created it) Player object. The init method may even have returned another instance than the one that is currently executing (some strange unique cocoa thing). And when that was successful then you crate a new CCSprite object and assign it to self. Self is then returned to the caller. (If you would not ARC - I assume you do - then this for sure would create a memory leak);

But the caller expects to deal with a Player object and later sends the leftButtonPressed message to it which the CCSprite cannot respond to.

That is, what the error message tells you.

You may use instead:

- (id)initSpriteWithFile(NSString*)fileName{
    if((self=[super initSpriteWithFile:fileName])){
        // Do any additional setup here. If you don't have any setup then do not overwrit the init method at all. 
        }
    return self;
}

or something like:

- (id)init{
    if((self=[super init])){
        [self setFileName:@"playerPlane.png"]; //This method may not exist at all but you may find an appropriate one in the docs. I am not used to CCSprit. I am just trying to explain the concept by example. 
        }
    return self;
}

Upvotes: 3

L&#233;o Natan
L&#233;o Natan

Reputation: 57040

You are calling self = [CCSprite spriteWithFile:@"playerPlane.png"]; but this creates a CCSprite instance rather than a Player instance.

I am guessing you do not have the source of CCSprite or there isn't a non-factory based initializer?

In this case, you would be better creating a class extension rather than subclassing.

Upvotes: 0

Related Questions