Получена ошибка EXC_BAD_ACCESS в проекте ARC с поддержкой cocos2d?

Я следовал за примером проекта от raywnderlich, чтобы рискнуть в моем первом приложении cocos2d.

В этом приложении движущиеся цели добавляются как показано ниже

-(void)addMonster
{    
    __strong CCSprite * monster = [CCSprite spriteWithFile:@"monster.png"];
    CGSize winSize=[CCDirector sharedDirector].winSize;
    int minY=monster.contentSize.height/2;
    int maxY=winSize.height-minY;
    int rangY=maxY-minY;
    int actualY=(arc4random()%rangY)+minY;

    monster.position=ccp(winSize.width+monster.contentSize.width, actualY);
    [self addChild:monster];
    monster.tag=1;
    int minDuration=2.0;
    int maxDuration=4.0;
    int actualDuration=(arc4random()%(maxDuration-minDuration))+minDuration;

    CCMoveTo *actionMove=[CCMoveTo actionWithDuration:actualDuration
                                             position:ccp(-monster.contentSize.width/2, actualY)];
    CCCallBlock *actionDone=[CCCallBlock actionWithBlock:^(CCSprite *node){
        [node removeFromParentAndCleanup:YES];// crashed at this point
        [_monsters removeObject:node];

    }];
    [monster runAction:[CCSequence actions:actionMove,actionDone,nil]];
    [_monsters addObject:monster];
}

И я планирую вышеупомянутый метод из -init метода моего подкласса CCLayerColor (сцена), как показано ниже

-(id)init
{ 
    // player adding code
    [self schedule:@selector(gameLogic) interval:1.0];
}
-(void)gameLogic
{
    [self addMonster];
}

т.е. перемещение слева на правый конец экрана Ipad

Моя проблема заключается в том, что приложение происходит сбой в CCCallBlock при доступе к объекту узла

Вместо того, чтобы загружать исходный код, я планировал повторить шаги с начальной точки, но до сих пор не могу найти, где он будет выпущен. помоги мне, сверстники

Обновление:- Я разместил скриншоты при аварии

2 ответа

Решение

Проблема в том, что используемый вами блок не соответствует ожидаемому интерфейсу. CCCallBlock action ожидает блок без параметров, но вы определили блок как принимающий параметр (узел). Я удивлен, что это даже компилируется. Конечно, переданный узел будет указателем мусора и падением при доступе.

Чтобы исправить это использование CCCallBlockN чей блок занимает CCNode* указатель в качестве параметра:

CCCallBlockN *actionDone = [CCCallBlockN actionWithBlock:^(CCNode *node){
    // ...
    }];

Похоже, проблема в том, что в actionDone нужно много убирать.

You add monster to self (+1), 
add to array _monsters (+1), 
then remove [node removeFromParentAndCleanup:YES]; (-1), 
[_monsters removeObject:node]; (-1), 
[self removeChild:node]; (-1)
+2, -3 —> bad access

Также (в данном конкретном случае) вы пытаетесь удалить узел два раза, сначала с помощью removeFromParentAndCleanup:, а затем из родительского removeChild: выберите что-то одно, вы не можете удалить что-то два раза

Другие вопросы по тегам