0

我不确定发生了什么,希望我能提供足够的相关代码来找到答案。我在 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 的一些打印输出。

每次应用程序崩溃时,事情都在“移动”,(end 永远不会被调用),并且 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 dev 的方法。我也会为任何调试技巧感到高兴(那些看起来像十六进制线的程序集对我来说并不是特别有启发性......)

4

1 回答 1

1

我在 NSZombies 的帮助下找出了问题,发现程序在尝试引用已释放的方法 handlePanFrom 时崩溃了。

问题的最终根源是 HomeLayer 被实例化了两次,第一次在 appDelegate.m 中,第二次在我执行 replaceScene 时。

这导致第一层最终丢失其所有引用并被解除分配,而gestureRecognizer 仍在尝试引用[layer handlePanFrom],从而导致崩溃。

通过将gestureRecognizer从appDelegate.m移动到HomeLayer.m解决了这个问题,对于需要跨多个层的手势的任何人,这里有一段代码将删除对视图的所有现有引用,然后添加一个以层中的方法为目标的新方法:

+(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;
}

希望这可以帮助将来尝试在视图中处理多个场景/图层的人=)

于 2013-01-29T06:48:30.883 回答