iphone cocos2d CCSprite EXC_BAD_ACCESS

Друзья, я новичок в программировании cocos2d и Mac в целом!

Я заметил, что ошибки EXC_BAD_ACCESS отнимают у меня большую часть времени... Возьмите следующий фрагмент кода из Учебник для компьютерщиков и пап...

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

здесь _player — глобальная переменная и доступна везде, я вызываю AddEnemyAtX: Y: и передаю какие-то координаты. Моя проблема в том, что в первый раз цикл работает нормально ... Но снова, когда управление передается от animateEnemyFinished к animateEnemy, приложение вылетает с упоминанием «EXC_BAD_ACCESS»!

Насколько я понял, ссылка на спрайт передается неправильно! Помощь!


person JaVadid    schedule 19.08.2010    source источник


Ответы (2)


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

дает вам автоматически выпущенный объект. Это означает, что вы не должны звонить

[enemy1 release]

и 2-й после того, как вы установили enemy1=nil

ты не можешь сделать [self animateEnemy:enemy1];

потому что вы даете nil animateEnemy:

Удаление [enemy1 release]; и enemy1 = nil;

из вашего кода должно решить вашу проблему.

person parceval    schedule 19.08.2010
comment
спасибо parceval... Это была моя ошибка, на самом деле я дал неправильный перепутанный фрагмент... Этот код был измененным кодом, который я использовал для хранения спрайтов в массиве, чтобы можно было решить справочную проблему, с которой я столкнулся!! Пожалуйста, найдите исправленный фрагмент и, пожалуйста, прокомментируйте его... - person JaVadid; 19.08.2010
comment
селектор неверен, это должно быть @selector(animateEnemyFinished:) в вашем коде отсутствует двоеточие, это означает, что когда действие перемещения завершилось, был вызван неизвестный метод. Вот и причина крушения. - person parceval; 19.08.2010
comment
Извини чувак!! опять опечатка!! Теперь я отредактировал вопрос, чтобы представить фактический фрагмент !!! еще раз извини чувак!!! - person JaVadid; 20.08.2010

Ух ты!! Атласт разобрался...

Небольшая ошибка... просто замена строки

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

с участием

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

сделал трюк! Из этого я понял, что @selector() передает идентификатор объекта, который его вызвал, но в то же время, когда мы используем его вместе с CCCallFuncN, он передает идентификатор узла, который является родительским для объекта, который его вызвал!

person JaVadid    schedule 20.08.2010