Beware of [self init]

In a new app I’m working on, I created a series of lightweight cocos2d sprite subclasses which simply call the superclass init with some parameters. As soon as I called it I ended up crashing with a weird looking stack trace showing lots of nested calls to init methods.

Screen shot 2011-03-06 at 2.18.44 PM.png

My init methods were pretty simple:


@implementation Gummybear

-(id)init {
    return [super initWithName: @"gummybear.png"];
}

@end

My superclass’s init method used CCSprite’s initWithSpriteFrameName: method.


- (id)initWithName: (NSString*)name
{
    self = [super initWithSpriteFrameName:name];
    if (nil != self) {
		// do some more initialization here
    }
    return self;
}

It ultimately ends up calling initWithTexture:, which is where the problem lies. It turns out initWithTexture: is calling [self init]. Guess which init method was getting called?


-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
	NSAssert(texture!=nil, @"Invalid texture for sprite");
	// IMPORTANT: [self init] and not [super init];
	if( (self = [self init]) )
	{
		[self setTexture:texture];
		[self setTextureRect:rect];
	}
	return self;
}

The fix was to simply change the name of my init method to something else.

3 responses to “Beware of [self init]

  1. Seems like calling [self init] is a bug in this case and should be reported as such to cocos2d project where it should be changed. Just too likely to cause exactly this problem. I asked @bbum for an opinion because I'm not 100% sure (it's late)… hopefully he'll feel like enlightening us 🙂

  2. So @bbum says your fix was the right one and it's not a bug like my foggy brain wanted to believe. Thanks @bbum! (feel free to delete both these comments as they don't add value)

  3. They did it because all of the real initialization is done in CCSprite's init method as the designated initializer.

Leave a Reply