Bug In My Code

Just spent countless hours over the past 10 days fighting a single bug in my next app. If you restarted the game, the app crashes. Took forever to figure out why. Turns out I was releasing memory that I shouldn’t have. That’s what I get for being a tidy programmer! UGH!

See highlighted block at the end of the snippet below.


-(id) initWithParentNode:(CCNode*)parentNode Player:(NSInteger)player Icon:(NSInteger)icon Color:(NSInteger)color{

// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {

CGSize winSize = [[CCDirector sharedDirector] winSizeInPixels];

NSString *strFile = [[NSString alloc] init];

if ((color == -1) && (icon == -1))
strFile = @"player_silver_car.png";
else {
switch (color)
{
case 0:
strFile = @"player_blue_";
break;
case 1:
strFile = @"player_yellow_";
break;
case 2:
strFile = @"player_red_";
break;
case 3:
strFile = @"player_green_";
break;
}

switch (icon)
{
case kPlayerChicken:
strFile = [strFile stringByAppendingString:@"chicken.png"];
break;
case kPlayerBoard:
strFile = [strFile stringByAppendingString:@"board.png"];
break;
case kPlayerTruck:
strFile = [strFile stringByAppendingString:@"truck.png"];
break;
case kPlayerCar:
strFile = [strFile stringByAppendingString:@"car.png"];
break;
}
}

playerLap = 1;
playerSwipes = 0;
playerSprite = [CCSprite spriteWithFile:strFile];

// Get Audio File
audioSoundFile = [self getAudioFile:icon];

// Load the Lap Sprites
// CCFadeOut *fo = [CCFadeOut actionWithDuration:.1];

lapSprite1 = [CCSprite spriteWithFile:@"lapindicator1.png"];
lapSprite1.position = CGPointMake(winSize.width/2, winSize.height/2);
lapSprite1.opacity = 0;
lapSprite2 = [CCSprite spriteWithFile:@"lapindicator2.png"];
lapSprite2.position = CGPointMake(winSize.width/2, winSize.height/2);
lapSprite2.opacity = 0;
lapSprite3 = [CCSprite spriteWithFile:@"lapindicator3.png"];
lapSprite3.position = CGPointMake(winSize.width/2, winSize.height/2);
lapSprite3.opacity = 0;

[parentNode addChild:lapSprite1];
[parentNode addChild:lapSprite2];
[parentNode addChild:lapSprite3];

// [lapSprite1 runAction:fo];
// [lapSprite2 runAction:fo];
// [lapSprite3 runAction:fo];
//
// Get start position from the bundle
RaceLayer *rl = (RaceLayer*)parentNode;
if (player == 1)
startPoint = rl.currentTrack.startPosition1;
else
startPoint = rl.currentTrack.startPosition2;
rl = nil;

[playerSprite setPosition:startPoint];

[parentNode addChild:playerSprite z:10 tag:kTagSpritePlayer + playerNumber];
playerSprite.rotation = -90;

playerStuckCount = 0;
soundOn = true;
/*
* Keeping this here for posterity.
* This one line actually creates a bug that prevents the screens from being reloaded
* It took me part-time work over 10 days to find this one error.
* I had to completely rip the code apart and slowly add parts back until I found the bug.
* COCOS2D caches images so it only loads them once.
* My assumption for the error is that by releasing the filename, when COCOS2D checks to see if the image is cached,
* the memory has been released and it throws a "BAD_ACCESS" error but does NOT say why.
*
[strFile release];
*/
// Manually schedule update via the undocumented CCScheduler class.
[[CCScheduler sharedScheduler] scheduleUpdateForTarget:self priority:0 paused:NO];
}

return self;
}