取消分配对象获取UIGestureRecognizer消息

时间:2010-05-12 14:45:40

标签: cocoa-touch ipad

我认为在接收双击时,会向根控制器发送通知,根控制器依次删除并释放视图。

问题是在视图发布后,它会收到另一个延迟的GestureRecognizer事件。

以下是“乐器”的信息:

Category        Event Type  RefCt   Timestamp   Address      Size   Responsible Library Responsible Caller
UIScrollView    Zombie          -1  00:06.166   0x55496a0    0                   UIKit  -[UIGestureRecognizer _updateGestureWithEvent:]


   0 CoreFoundation ___forwarding___
   1 CoreFoundation _CF_forwarding_prep_0
   2 UIKit -[UIGestureRecognizer _updateGestureWithEvent:]
   3 UIKit -[UIGestureRecognizer _delayedUpdateGesture]
   4 UIKit _UIGestureRecognizerUpdateObserver
   5 UIKit _UIGestureRecognizerUpdateGesturesFromSendEvent
   6 UIKit -[UIWindow _sendGesturesForEvent:]
   7 UIKit -[UIWindow sendEvent:]
   8 UIKit -[UIApplication sendEvent:]
   9 UIKit _UIApplicationHandleEvent
  10 GraphicsServices PurpleEventCallback
  11 CoreFoundation CFRunLoopRunSpecific
  12 CoreFoundation CFRunLoopRunInMode
  13 GraphicsServices GSEventRunModal
  14 GraphicsServices GSEventRun
  15 UIKit UIApplicationMain
  16 ipadapp main /Users/test/Projects/app/ipadapp/main.m:7
  17 ipadapp start

UIScrollView似乎在正确的时间发布。

问题是这个额外的手势事件到来的原因。

5 个答案:

答案 0 :(得分:7)

我不知道我是否有完全相同的问题,但这是我为我做的事情:

Xcode中的

1- Enable Zombie mode可以获得准确的信息,以确保您正在查看正确的位置。 之后,您将收到如下消息: [OverView gestureRecognizerFailed:]:发送到解除分配的实例0x53d6d00的消息

2-现在你知道了确切的问题,在删除它之前停用这个对象的手势:

    // I have to remove the gestures, because a GesturerecongizerFailed can arrive after the view has been deallocated
    for (UIGestureRecognizer* gesture in self.overView.gestureRecognizers) {
        NSLog(@"Desactive un gesture");
        gesture.delegate = nil ; 
        gesture.enabled = NO;
    }
    // Remove the view from the display
    [self.overView removeFromSuperview];
    self.overView = nil;

这应该可以解决问题。

[编辑] 另一个对我有用的解决方案:不要将'autorelease'用于手势识别器。在大多数情况下,您可以在将识别器添加到视图后直接释放它。

答案 1 :(得分:2)

在您的控制器被取消分配后,您的手势识别器似乎正在向您的控制器发送回调。在取消分配控制器之前,请确保从附加的视图中删除手势识别器。

在你的控制器类中,你可能会设置你的手势识别器:

- (void)loadView {
    [super loadView];
    _view = [[UIView alloc] init];
    _doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleDoubleTap:)];
    [_view addGestureRecgonizer:_doubleTapGestureRecognizer];
}

因此,请确保在控制器的dealloc方法中删除手势识别器:

- (void)dealloc {
    [_view removeGestureRecognizer:_doubleTapGestureRecognizer];
    [_doubleTapGestureRecognizer release];
    [_view release];
    [super dealloc];
}

答案 2 :(得分:0)

根据定义,延迟手势会在稍微延迟后发送。此(UIScrollViewDelayedTouchesBeganGestureRecognizer)用于确保捏合和平移手势获得更高的优先级。

手势识别器不会保持其状态以避免保留周期。因此,当此识别器触发时,它将发送到解除分配的视图。

您可以延迟视图的-release(例如-performSelector:withObject:afterDelay:)。或者不是删除视图,只需将其设置为hidden

答案 3 :(得分:0)

简单地执行此操作是否有任何不妥之处:

if (gestureRecognizer) {
    if ((touch.view == UIButtonTypeCustom)) {
        return NO;
    }
    return YES;
} else return NO;

答案 4 :(得分:0)

这是我如何解决它的明显解决方案..确保释放您的实际视图。我的观点有一堆我正在发布的子视图,但我没有发布我的实际视图。我做完之后,程序很好。

相关问题