问题总结:
在启动应用程序并按“New Game”后,我使用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
对象。然后,使用该标签删除"new"的GamePiece
对象,并添加其他对象。我的问题?
点按
GamePiece
后,"new"游戏片段会适当显示,但是当我多次点击后,它就会崩溃!我的意思是,我点击GamePiece
,出现新的gamePieces。然后,如果我点击另一个GamePiece
,我会把手放在心上等待崩溃。.有时它崩溃了,而其他时候却没有...第三次,第四次,第五次……等等。我获得了高分崩溃前10次抽头的时间:P ...太随机了...我的理论:
参见注释行
//<------THIS
,每次我点击屏幕时CCLOG
都会被调用任意次,直到找到满足if语句的GamePiece
,这是正常的,因为我同时加载了许多GamePiece
对象。当它崩溃时(没有任何堆栈跟踪或消息),此
CCLOG
会被调用几次,并且永远不会使其进入if语句!我认为是因为它正在尝试向已被GamePiece
删除的removeChildWithTag:
发送触摸消息。但是我已经在dealloc中调用了[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
,这导致了一个非常重要的事实:如果我在点击另一个
GamePiece
之后等待几秒钟再点击另一个,则我更有可能不会崩溃! 感觉就像我给它时间调用dealloc并删除了触摸委托(delegate)...
编辑:
我突然想到在dealloc中添加一个
CCLOG
,但是从来没有被调用过...END EDIT
并且不确定是否很明显,但是如果我不删除新添加的GamePieces,则游戏永远不会崩溃...但是我需要删除它们:P
请帮忙,我已经为这个问题解决了好几天了。
最佳答案
这个!!:
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:-1 swallowsTouches:YES]; //Important...
是有史以来最大的错误!
这段简洁的代码:
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
实际上保留了委托(delegate)...而我从未达到过dealloc,也从未从touch调度程序中删除DeleteDelegate并导致灾难...
编辑:
好的,有人想知道我最终在哪里删除了代表!我很惊讶没有提到那件事!
- (void)onExit {
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
// Never forget this!!
[super onExit];
}