views:

120

answers:

2

Friends i am new to cocos2d programming and Mac in general!

I have noticed this EXC_BAD_ACCESS errors ruining most of my time... Take the following snippet of code from the Geek & Dad's tutorial...

-(void) AddEnemyAtX:(int)x Y:(int)y {
    CCSprite *enemy1 = [CCSprite spriteWithFile:@"enemy1.png"];
    enemy1.position = ccp(x,y);
    [self addChild:enemy1];
    [self animateEnemy:enemy1];
    NSLog(@"%@", enemy1);
}

-(void) animateEnemy:(CCSprite *)enemy {
    ccTime actualDuration = .5;
    id actionMove = [CCMoveBy actionWithDuration:actualDuration
           position:ccpMult(ccpNormalize(ccpSub(_player.position,enemy.position)), 10)];
    id actionFinished = [CCCallFunc actionWithTarget:self
           selector:@selector(animateEnemyFinished:)];
        [enemy runAction:[CCSequence actions:actionMove,actionFinished,nil]];
}

-(void) animateEnemyFinished:(id)sender {
    CCSprite *enemy = (CCSprite *)sender;
    [self animateEnemy:enemy];
}

here _player is a global variable and accessible everywhere, I call AddEnemyAtX: Y: and pass some coordinates. My problem is the first time the loop runs fine... But again when the control is passed from animateEnemyFinished to animateEnemy then the app crashes mentioning "EXC_BAD_ACCESS"!

From what i figured out, the Sprite reference is not passed correctly! Help!

A: 

CCSprite *enemy1 = [CCSprite spriteWithFile:@"enemy1.png"];

gives you an autoreleased object. This means you should not call

[enemy1 release]

and 2nd after you set enemy1=nil

you can't do [self animateEnemy:enemy1];

because you give nil to animateEnemy:

Removing [enemy1 release]; and enemy1 = nil;

from your code should fix your problem.

parceval
thanx parceval... It was my mistake, actually i had given the wrong mixed up snippet... That code was the modified code i used to store the sprites in an Array so that the reference problem i was facing can be solved!!Please find the snippet corrected and plz comment on it...
JaVadid
the selector is wrongit must be @selector(animateEnemyFinished:)the colon is missing in your code, means that when the move action finished an unknown method was called. Thats the reason for the crash.
parceval
Sorry dude!! again a typo error!! I have edited the question now to represent the actual snippet!!! sorry again dude!!!
JaVadid
A: 

Wow!! Atlast figured it out...

A small mistake... just replacing the line

id actionFinished = [CCCallFunc actionWithTarget:self
           selector:@selector(animateEnemyFinished:)];

with

id actionFinished = [CCCallFuncN actionWithTarget:self
           selector:@selector(animateEnemyFinished:)];

did the trick! What i understood from this was that @selector() passes the id of the object which called upon it but at the same time when we use it along with CCCallFuncN it passes the id of the Node just parent to the object which called upon it!

JaVadid