Нераспределенный объект получает сообщение UIGestureRecognizer - PullRequest
5 голосов
/ 12 мая 2010

У меня есть вид, что при получении двойного касания отправляет уведомление корневому контроллеру, который по очереди удаляет и освобождает вид.

Проблема в том, что после того, как представление было выпущено, оно получает другое отложенное событие GestureRecognizer.

Ниже приведена информация от '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, кажется, выпущен в правильное время.

Вопрос в том, почему прибывает это дополнительное жестовое событие.

Ответы [ 5 ]

7 голосов
/ 28 сентября 2010

Я не знаю, была ли у меня точно такая же проблема, но вот как я сделал для своей:

1- Включите режим зомби в Xcode, чтобы получить точное сообщение, чтобы убедиться, что вы смотрите в правильном месте. После этого вы получите следующее сообщение: [OverView gestRecognizerFailed:]: сообщение отправлено на освобожденный экземпляр 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;

Это должно сработать.

[EDIT] Другое решение, которое сработало для меня: не использовать 'autorelease' для распознавателей жестов . В большинстве случаев вы можете сразу же разблокировать распознаватель после добавления его в представление.

2 голосов
/ 31 июля 2011

Похоже, ваш распознаватель жестов отправляет обратный вызов вашему контроллеру после того, как ваш контроллер был освобожден. Убедитесь, что вы удалили распознаватель жестов из вида, к которому вы его прикрепили, прежде чем освободить свой контроллер.

В вашем классе контроллера вы, вероятно, настроили свой распознаватель жестов примерно так:

- (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];
}
0 голосов
/ 07 июля 2012

Вот очевидное решение того, как я это решил .. не забудьте опубликовать ваш фактический вид. У моего представления было множество подпредставлений, которые я выпускал, но я не опубликовал свое действительное представление. После того, как я сделал, программа была в порядке.

0 голосов
/ 01 июня 2011

что-то не так с этим:

if (gestureRecognizer) {
    if ((touch.view == UIButtonTypeCustom)) {
        return NO;
    }
    return YES;
} else return NO;
0 голосов
/ 12 мая 2010

Задержанные жесты, по определению, отправляются после небольшой задержки. Это (UIScrollViewDelayedTouchesBeganGestureRecognizer) используется для обеспечения более высокого приоритета жестам зажима и панорамирования.

Распознаватель жестов не будет сохранять свое состояние, чтобы избежать цикла сохранения. Следовательно, когда этот распознаватель срабатывает, он отправляет в освобожденное представление.

Вы можете отложить -release просмотра (например, с -performSelector:withObject:afterDelay:). Или вместо того, чтобы удалить вид, вы можете просто установить его hidden.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...