Cocos2D удалить CshildByTag сбой? - PullRequest
       9

Cocos2D удалить CshildByTag сбой?

2 голосов
/ 25 февраля 2011

Краткое описание проблемы: После запуска приложения и нажатия «Новая игра» я использую CCDirector для перехода к GameScene. Там я добавляю 32 GamePiece объектов, где эти объекты обрабатывают события касания следующим образом:

@interface GamePiece : NSObject <CCTargetedTouchDelegate>{  

    CCSprite* sprite;

    NSInteger row;
    NSInteger column;

}

//-(void)moveToRow:(NSInteger)newRow column:(NSInteger)newColumn;
-(id)initWithRow:(NSInteger)aRow column:(NSInteger)aColumn tag:(NSInteger)tag parent:(CCNode*)parent;
+(id)gamePieceWithRow:(NSInteger)aRow column:(NSInteger)aColumn tag:(NSInteger)tag parent:(CCNode*)parent;

@end

GamePiece.m:

...
- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    CGPoint touchLocation = [GameScene locationFromTouch:touch];

    CCLOG(@"(%i, %i)", row, column); //<-----THIS!!!

    //Crash never makes it here....

    // Check if this touch is on the Spider's sprite.
    BOOL isTouchHandled = CGRectContainsPoint([sprite boundingBox], touchLocation);
    if (isTouchHandled){        
        id parent = sprite.parent;
        [parent gamePieceSelected:self inRow:row column:column];
    }

    return isTouchHandled;
}

...

- (void)dealloc {
    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; //Important...
    [super dealloc];
}
@end

Хорошо, так что после того, как я загрузил 32 части, я загружаю еще больше частей, используя метод:

[parent gamePieceSelected:self inRow:row column:column];

следующим образом: (GameScene.m)

-(void)gamePieceSelected:(GamePiece*)aGamePiece inRow:(NSInteger)row column:(NSInteger)column{
    [self removeChildByTag:18 cleanup:YES];
    //Array of index Path!!! row = row, section = column
    NSArray* moves = [self availableMovesForRow:row column:column];

    for(NSIndexPath* index in moves){ //Please forgive me for using NSIndexPath!! 
        [GamePiece gamePieceWithRow:[index row] column:[index section] tag:18 parent:self];
    }
}

Таким образом, в основном, когда вы нажимаете GamePiece, я добавляю другие GamePiece объекты с тегом = 18. Затем я использую этот тег, чтобы удалить «новые» GamePiece объекты и добавить другие ..

Моя проблема?

После нажатия GamePiece «новые» игровые фигуры появляются соответствующим образом, но вылетает после того, как я нажимаю более одного раза! Я имею в виду, я нажимаю GamePiece, появляется новая игра. Затем, если я коснусь другого GamePiece, я положу руку на сердце в ожидании сбоя .. Иногда он падает, иногда нет ... В третий раз, четвертый, пятый ... и т. Д. Мне удалось рекорд 10 нажатий, прежде чем он рухнул: P ... так случайно ...

Моя теория:

См. Строку комментария //<------THIS, CCLOG вызывается произвольное количество раз каждый раз, когда я нажимаю на экран, пока не найдет GamePiece, который удовлетворяет оператору if, что довольно нормально, поскольку у меня много GamePiece объекты загружаются одновременно ..

Когда происходит сбой (без трассировки стека или сообщений), этот CCLOG вызывается несколько раз и никогда не попадает в оператор if !! Я думаю, это потому, что он пытается отправить сенсорное сообщение на GamePiece, который был удален removeChildWithTag:. Но я уже вызываю [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; в dealloc, что приводит к очень важному факту:

Если я подожду несколько секунд после нажатия GamePiece, прежде чем коснусь другого, у меня больше шансов не разбиться !!

Такое ощущение, что я даю время позвонить в dealloc и удалить делегата для касания ...

EDIT: Мне пришло в голову добавить CCLOG в dealloc, и он никогда не вызывался ... КОНЕЦ РЕДАКТИРОВАНИЯ

И я не уверен, что это очевидно, но если я НЕ удаляю недавно добавленные GamePieces, игра никогда не падает, но мне нужно удалить их: P

Пожалуйста, помогите, я боролся с этой проблемой в течение нескольких дней>.

1 Ответ

2 голосов
/ 26 февраля 2011

ЭТО !!:

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:-1 swallowsTouches:YES]; //Important...

была самая большая ошибка когда-либо !!

Этот аккуратный кусок кода:

[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];

на самом деле сохраняет делегата ... и я никогда не добираюсь до Deloc, и никогда не удаляю Delegate из диспетчера касаний и не вызываю катастрофу ...

<ч />

EDIT:

Хорошо, кто-то хочет знать, где я в итоге удалил делегата! И я удивлен, что я не упомянул об этом!

- (void)onExit {
    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
    // Never forget this!!
    [super onExit];
}
...