【问题标题】:Cocos2D removeChildByTag crash?Cocos2D removeChildByTag 崩溃?
【发布时间】:2011-07-04 11:39:50
【问题描述】:

问题总结: 启动应用程序并按“新游戏”后,我使用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 时,我会添加其他带有标签 = 18 的 GamePiece 对象。然后我使用此标签删除“新”GamePiece 对象,并添加其他对象..

我的问题?

在点击GamePiece 后,“新”游戏片段会适当出现,但在我多次点击后它会崩溃!我的意思是,我点击GamePiece,新的gamePieces 出现了。然后,如果我点击另一个GamePiece,我把手放在心上等待崩溃。有时它会崩溃,有时它不会……第三次,第四次,第五次……等等。我成功了在崩溃之前获得 10 次点击的高分:P ... 如此随机....

我的理论:

查看评论行//&lt;------THIS,每次我点击屏幕时,CCLOG 都会被调用任意次数,直到找到满足 if 语句的GamePiece,这很正常,因为我有很多GamePiece对象同时加载..

当它崩溃时(没有任何堆栈跟踪或消息),这个CCLOG 会被调用几次,并且永远不会在 if 语句中出现!我认为这是因为它试图向已被removeChildWithTag: 删除的GamePiece 发送触摸消息。但我已经在dealloc 中调用了[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];,这导致了一个非常重要的事实:

如果我在点击 GamePiece 后等待几秒钟,然后再点击另一个,我就有更高的机会不崩溃!!

感觉就像我在给它时间调用dealloc,并移除触摸委托...

编辑: 我突然想到在 dealloc 中添加一个CCLOG,但它从未被调用... 结束编辑

我不确定这是否明显,但如果我不删除新添加的 GamePieces,游戏永远不会崩溃...但我需要删除它们:P

请帮忙,我已经解决这个问题好几天了>。

【问题讨论】:

  • 我的时间真的很短...我什至不能等待两天开始赏金>.

标签: iphone crash cocos2d-iphone removechild touch-event


【解决方案1】:

这!!:

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

这是有史以来最大的错误!

这段简洁的代码:

[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];

实际上保留了委托......我从来没有达到dealloc,也从来没有从触摸调度程序中删除Delegate并导致灾难......


编辑:

好的,有人想知道我最终在哪里删除了代表!我很惊讶我没有提到这一点!

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多