Правильный способ подключения/удаления UIGestureRecognizers

Каков правильный способ подключения и удаления UIGestureRecognizer в представлении?

Я обычно создаю и прикрепляю UIGestureReconizers в -viewDidLoad. Должен ли я использовать removeGestureRecognizer в -viewDidUnload? Или они автоматически удаляются?

Например, это лучший способ создать свойство UIGestureRecognizer и инициализировать его в методе initController init, а затем прикрепить/удалить это свойство gestureRecognizer в -viewDidAppear/-viewDidDisappear?

(Примечание: я использую ARC)

Спасибо.

Ответ 1

По существу вы можете создавать, добавлять и удалять распознаватели жестов, когда это имеет смысл. И "когда это имеет смысл" варьируется в зависимости от нескольких вещей, но обычно только от того, сохраните ли вы их как иваров. С ARC ключ управляет сильными ссылками; С ARC ivars по умолчанию сильные.

Итак, скажем, вы добавляете распознаватель крана. В этом случае вам не нужно снова обращаться к распознавателю. Я бы создал его так:

-(void)viewDidLoad{
    [super viewDidLoad];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [self.view addGestureRecognizer:tap];
}

В этом сценарии вам не нужно ничего другого, чтобы управлять этим распознавателем. Система взглядов держит на ней сильную ссылку. Все, что вы делаете, это сидеть сложа руки и ждать, пока он вызовет handleTap:. Когда выгрузите представление, этот распознаватель будет отменен.

Этот сценарий также не был бы хорошим дополнением к этому распознавателю в viewWillAppear:, так как не сложно представить серию событий, которые приведут к созданию нескольких распознавателей.

Таким образом, логически, если вы хотите добавить распознаватель в методы внешнего вида, вам нужно будет провести некоторую ссылку на них в ivar. Но опять же это не всегда плохая идея. Как правило, причиной, по которой вам нужна ссылка на ваши распознаватели, является помощь в логике методов <UIGestureRecognizerDelegate>, если они используются.

Я лично никогда не добавлю распознавателя в метод initWith.. для вложения позже. Единственное преимущество заключается в том, что любой распознаватель, созданный там, будет храниться в течение всего срока действия контроллера вида. Но так как распознаватель довольно явно является частью системы представлений, этот тип muddies-up MVC, который Cocoa является большим. Также в режиме с низкой памятью состояние контроллеров в стеке навигации очищается, но в этом случае распознаватель может по-прежнему использовать память (а не огромные объекты) по какой-либо причине.

Вы, конечно, можете добавить распознаватель в метод view(Will/Did)Appear: и удалить его в view(Will/Did)Disappear:. Не мое предпочтение. Я не думаю, что только потому, что представление modal представлено и удалено, или произошло переключение push/pop, что я должен удалить и повторно добавить мои распознаватели.

Я бы рекомендовал почти всегда использовать viewDidLoad для создания и прикрепления распознавателей. Просто помните, чтобы скрыть любые сильные ссылки на них в viewDidUnload, чтобы помочь в ситуации с низкой памятью. И снова с ARC нет необходимости ничего делать с ivars в dealloc.

Ответ 2

viewDidUnload вызывается только в условиях низкой памяти и не может быть вызвана вообще. Поэтому любые распознаватели жестов, удаленные в viewDidUnload, также должны быть удалены в dealloc. EIther метод, который вы упомянули, в порядке.

Ответ 3

ok, тогда viewWillAppear:Animated и viewWillDisappear:animated будет лучшим выбором для любых действий с жестами, насколько мне известно.