UIPanGestureRecognizer意外崩溃

时间:2013-01-28 07:04:51

标签: objective-c uipangesturerecognizer

我不确定发生了什么,希望我能提供足够的相关代码来找到答案。我在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开发方式。我也会对任何调试技巧感到高兴(那些看起来十六行的装配对我来说并不特别有启发性......)

1 个答案:

答案 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;
}

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