我不确定发生了什么,希望我能提供足够的相关代码来找到答案。我在appDelegate.m中设置了手势识别器:
CCScene *scene = [HomeLayer scene];
HomeLayer *layer = (HomeLayer *) [scene.children objectAtIndex:0];
UIPanGestureRecognizer *gestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:layer action:@selector(handlePanFrom:)] autorelease];
[director_.view addGestureRecognizer:gestureRecognizer];
m._gestureRecognizer = gestureRecognizer;
我已插入一些调试消息,试图查明应用崩溃的时间点:
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {
NSLog(@"Handle Pan From");
以及ccTouchBegan / Moved / Ended的一些打印输出。
每当应用程序崩溃时,它就会移动",(结束永远不会被调用),handlePanFrom也永远不会被调用。
背景信息:我的应用程序有用于在场景之间切换的按钮,例如:
- (void) doSomethingThree: (CCMenuItem *) menuItem
{
NSLog(@"The third menu was called");
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[HomeLayer scene] ]];
}
如果我启动我的应用程序直接进入HomeLayer场景并尝试拖动,应用程序会在100%的时间内立即崩溃(ccMoved会在崩溃前被调用1-2次)。单击不会导致应用程序崩溃,只会导致调用handlePanFrom的任何内容。
奇怪的是,如果我在任何其他场景上拖动,应用程序不会崩溃,并成功调用handlePanFrom。然后,当我回到HomeLayer场景并拖拽时,它会在一段时间内不会崩溃,这似乎直接与我在不同场景上拖动的时间有关。
之前有没有人见过这些症状?我不确定我提供的信息是否相关或正确,我仍然在尝试了解iphone开发方式。我也会对任何调试技巧感到高兴(那些看起来十六行的装配对我来说并不特别有启发性......)
答案 0 :(得分:1)
我在NSZombies的帮助下找出了问题,发现该程序在尝试引用deallocated方法handlePanFrom时崩溃。
问题的根本原因是HomeLayer被实例化了两次,第一次在appDelegate.m中,第二次是我在执行replaceScene时。
这导致第一层最终失去所有引用并被释放,而gestureRecognizer仍然试图引用[layer handlePanFrom],导致崩溃。
通过将gestureRecognizer从appDelegate.m移动到HomeLayer.m来修复问题,对于需要跨多个层的手势的人来说,这里有一段代码可以删除对视图的任何现有的gestureRecognizer引用,以及然后添加一个新的目标方法:
+(CCScene *) scene
{
HomeLayer *layer = [HomeLayer node];
[scene addChild: layer];
for (UIGestureRecognizer *gr in [[CCDirector sharedDirector].view gestureRecognizers]) {
// note that sharedDirector is a singleton and therefore is the same CCDirector
// as the one used in appDelegate.m
[[CCDirector sharedDirector].view removeGestureRecognizer:gr];
}
UIPanGestureRecognizer *gestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:layer action:@selector(handlePanFrom:)] autorelease];
[[CCDirector sharedDirector].view addGestureRecognizer:gestureRecognizer];
return scene;
}
希望这可能有助于将来尝试在视图中处理多个场景/图层的人=)