问题摘要:
在我启动应用程序并按“新游戏”后,我使用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
个对象,其中包含tag = 18.然后我使用此标记删除“新”GamePiece
个对象,然后添加其他.. ..
我的问题?
在录制GamePiece
之后,“新”游戏片段会正确显示,但在我点击多次后它会崩溃!我的意思是,我点击GamePiece
,新的游戏片出现了。然后,如果我点击另一个GamePiece
,我会把手放在我的心脏上等待崩溃。有时它会崩溃,有时它不会崩溃......第三次,第四次,第五次......等等。在它崩溃之前我管理了10个水龙头的高分:P ......太随机了......
我的理论:
请参阅注释行//<------THIS
,每次点击屏幕时,CCLOG
都会被调用任意次,直到找到满足if语句的GamePiece
,这有点儿正常,因为我同时加载了很多GamePiece
个对象..
当它崩溃时(没有任何堆栈跟踪或消息),这个CCLOG
会被调用几次,并且永远不会在if语句中进行!我认为这是因为它正在尝试向GamePiece
已移除的removeChildWithTag:
发送触摸消息。但我已经在dealloc中调用了[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
,这导致了一个非常重要的事实:
如果我在点击GamePiece
之前等待几秒钟,然后点击另一个,我有更大的机会不会崩溃!!
感觉我正在给它时间调用dealloc,并删除触摸代表......
修改
在我看来,在dealloc中添加CCLOG
,它从未被调用过......
结束编辑
我不确定这是否显而易见,但如果我不删除新添加的GamePieces,游戏永远不会崩溃......但我需要删除它们:P
请帮助,我已经和这个问题打了几天&gt;。
答案 0 :(得分:2)
此!!:
[[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];
}