views:

107

answers:

2

I have a view that on receiving double tap, sends a notification to the root controller, who in turns removes and releases the view.

The problem is that after the view has been released, it receives another delayed GestureRecognizer event.

Following is the info from 'Instruments':

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 seems to be released at the correct time.

Question is why this additional gesture event is arriving.

A: 

Delayed gestures, by definition, are sent after a little delay. This (UIScrollViewDelayedTouchesBeganGestureRecognizer) is used to ensure the pinch and pan gestures get a higher priority.

A gesture recognizer will not retain its state to avoid a retain cycle. Hence, when this recognizer fires, it will send to a deallocated view.

You could delay the -release of the view (e.g. with -performSelector:withObject:afterDelay:). Or instead of removes the view, you could just set it hidden.

KennyTM
Thanks for the answer. I find both your options to sound somewhat like bad workarounds (no offense...) - isn't there a way to tell the gesture recognizers to delete all pending messages? I have already tried calling 'removeTarget' on the gesture recognizer and 'removeGestureResognixer' on the view but still no luck.
LK
@LK: Did you try setting `.gestureRecognizers` to nil?
KennyTM
Actually didn't solve it... Even with a delay I am getting this.
LK
A: 

I don't know if I had exactly the same problem but here is how I did for mine:

1- Enable Zombie mode in Xcode to get a precise message in order to be sure you are looking at the correct place. After that you will get a message like this : [OverView gestureRecognizerFailed:]: message sent to deallocated instance 0x53d6d00

2- Now that you know the exact problem, desactivate gestures on this object before removing it :

    // 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;

This should do the trick

CedricSoubrie