Подтвердить что ты не робот

Когда отказаться от подписки на NSNotification в UIView

Я использую следующие NSNotifications в UIView, так что представление может быть уведомлено, когда появляется UIKeyboard и настраивает его положение (кадр) на экране:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];

Два вышеупомянутых уведомления подписываются в рамках метода -init UIView. Где лучше всего отказаться от подписки на эти уведомления после того, как представление исчезло за пределами экрана? В настоящий момент приложение сбой, всякий раз, когда UIKeyboard появляется в другом представлении, по-видимому, потому что уведомление все еще отправляется в выпущенный UIView.

Кроме того, есть ли лучшее место для подписки на уведомления, помимо метода -init?

Спасибо за любую помощь.

4b9b3361

Ответ 1

-[UIView willMoveToWindow:] и -[UIView didMoveToWindow] вызывается даже тогда, когда представление удаляется из окна. В этом случае аргумент окна (или свойство окна в случае -didMoveToWindow) будет равен нулю. е:.

- (void)willMoveToWindow:(UIWindow *)newWindow {
    if (newWindow == nil) {
        // Will be removed from window, similar to -viewDidUnload.
        // Unsubscribe from any notifications here.
    }
}

- (void)didMoveToWindow {
    if (self.window) {
        // Added to a window, similar to -viewDidLoad.
        // Subscribe to notifications here.
    }
}

За исключением нескольких краевых случаев, это безопасный способ сделать это. Если вам нужно больше контроля, вы можете наблюдать скрытое свойство окна, к которому принадлежит ваше представление.

Ответ 2

Я помещаю свои removeObserver: вызовы в -dealloc.

У нас пока не было проблем.

Ответ 3

Во-первых, вы должны учитывать, когда хотите прекратить получать уведомления:

  • Когда просмотр освобожден
  • Когда вид исчезает

Вы всегда должны проверить, соблюдает ли ваше наблюдение уведомления и вызывает -removeObserver: в -dealloc. Кроме того, если вы считаете 2, переопределите -viewWillDisappear или -viewDidDisappear или любую другую точку, где вы управляете иерархией представления UIViewController.

Я рекомендую поместить логику в UIViewController, потому что в терминах отношений UIView не имеет своего фрейма.

Ответ 4

Окончательный ответ (например, убедитесь, что объект перестает ссылаться на NSNotificationCenter, когда заканчивается его жизненный цикл), чтобы делать, как @Tom предлагает и удаляет себя в качестве наблюдателя в dealloc.

Субъективный ответ - это также хорошая практика прекратить наблюдение, когда уведомления больше не относятся к объекту. Это полностью зависит от вас, чтобы решить, основываясь на дизайне вашего приложения. Например, если у вас есть представления, которые остаются в живых, но приходят и выходят из поля зрения, вы можете начать наблюдать, когда они добавляются в подпункт, и прекращают наблюдать, когда они удаляются.

WRT, где логика уведомления должна находиться (в режиме просмотра против контроллера), что также зависит от вас, очевидно, что она может работать в обоих направлениях. Я бы принял решение на основе обстоятельств. Если обработка уведомления в представлении требует нажатия логики приложения в представление (т.е. Обработки представления как контроллера), тогда это красный флаг.

Ответ 5

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

Ответ 6

Чтобы отказаться от подписки, вы можете использовать

- (void)removeObserver:(id)notificationObserver

или

- (void)removeObserver:(id)notificationObserver name:(NSString *)notificationName object:(id)notificationSender

Оба метода - это методы NSNotificationCenter экземпляров.

Посмотрите Справочник класса NSNotificationCenter

Ответ 7

Как практика для клавиатурных уведомлений, я обычно использую

addObserver

в

viewWillAppear

и

removeObserver

в

viewWillDisAppear

отлично работает для меня каждый раз, и это гарантирует, что уведомление о клавиатуре не передается в представление, которое не находится на экране, что предотвращает сбой приложения из-за ложных недочетов клавиатуры.