代码之家  ›  专栏  ›  技术社区  ›  LK.

释放对象获取uigestureRecognizer消息

  •  5
  • LK.  · 技术社区  · 15 年前

    我有一个视图,在接收到双击时,会向根控制器发送一个通知,然后根控制器会移除并释放该视图。

    问题是,在释放视图之后,它会收到另一个延迟的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 回复  |  直到 15 年前
        1
  •  7
  •   CedricSoubrie    13 年前

    我不知道我是否也有同样的问题,但我是如何做到的:

    1个- Enable Zombie mode 在xcode中获取精确的消息,以确保您看到的位置正确。 之后,您将收到这样的消息: [概述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” 是的。在大多数情况下,您可以在将识别器添加到视图后直接释放它。

        2
  •  2
  •   nefaurk    13 年前

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

    在控制器类中,您可能会设置如下手势识别器:

    - (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];
    }
    
        3
  •  0
  •   kennytm    15 年前

    根据定义,延迟的手势是在稍有延迟之后发送的。这个(uiscrollyviewdelayedtouchesbegangesturerecognizer)用于确保捏和平移手势获得更高的优先级。

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

    你可以推迟 -release 视图(例如 -performSelector:withObject:afterDelay: )中。或者不删除视图,只需设置它 hidden 是的。

        4
  •  0
  •   jangelo42    14 年前

    这么做有什么不对吗?

    if (gestureRecognizer) {
        if ((touch.view == UIButtonTypeCustom)) {
            return NO;
        }
        return YES;
    } else return NO;
    
        5
  •  0
  •   markckim    12 年前

    这里有一个很明显的解决方法…确保释放您的实际视图。我的视图有很多子视图,我正在发布,但我没有发布我的实际视图。在我做了之后,程序很好。