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

Какой лучший способ добавитьObserver/removeObserver с NSNotificationCenter?

Я использовал addObserver в viewDidLoad: и removeObserver в dealloc:. Код:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(refreshData)
                                                 name:AnyNotification
                                               object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AnyNotification
                                                  object:nil];
}

Но, согласно некоторым статьям, лучше addObserver в viewDidAppear: и removeObserver в viewDidDisappear:. Код:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(refreshData)
                                                 name:AnyNotification
                                               object:nil];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AnyNotification
                                                  object:nil];
}

Итак, какой лучший способ добавитьObserver/removeObserver?

4b9b3361

Ответ 1

это зависит от вашего сценария, обычно лучший подход - добавить viewDidLoad (устарело, используйте dealloc сейчас) и удалить в dealloc и viewDidUnload, но в некоторых случаях у вас есть один и тот же метод в разных классах, например, эффекты пользовательского интерфейса, и вы хотите вызвать только текущий метод экрана, использующий уведомление, тогда вам нужно будет добавить наблюдателя в viewWillAppear и удалить его в viewWillDisappear или viewDidAppear/viewDidDisappear

Редактировать: примечание от комментариев, спасибо @honey.

Хотя теперь, начиная с iOS 9, вам больше не нужно заботиться об удалении наблюдателя. См. Примечания к выпуску Apple: "В OS X 10.11 и iOS 9.0 NSNotificationCenter и NSDistributedNotificationCenter больше не будут отправлять уведомления зарегистрированным наблюдателям, которые могут быть освобождены.

Ответ 2

Я обычно помещал бы его в -viewDidAppear: и -viewDidDisapear: (или -viewWillAppear: и -viewWillDisappear:) просто потому, что в каждом случае, с которым я сталкивался, меня интересует только уведомление, если представление действительно отображается.

Вероятно, это преждевременная оптимизация (ваш код для обработки уведомления может занять некоторое время, но может быть бесполезным, если представление не отображается), но тогда он также не содержит больше кода - это тот же код только в другом методе...

Ответ 3

Не забудьте NSKeyValueObservingOptionInitial. Я использую его с viewWillAppear/viewWillDisappear, поэтому мой пользовательский интерфейс всегда обновлен, даже если я скрою этот контроллер представлений, сохраняя ресурсы, потому что я не буду обновлять его до тех пор, пока он не будет показан снова.

Ответ 4

-viewWillAppear: + -viewWillDisappear: лучше, чем -viewDidAppear: + -viewDidDisapear:, потому что они всегда называются одинаковым числом раз.

Ответ 5

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

Это может быть на viewDidLoad:, viewWillAppear: или когда пользователь нажимает кнопку и т.д.

Я приведу вам небольшой пример:

В моем приложении есть вкладка, а в некоторых контроллерах представлений я показываю некоторую информацию, загруженную из Интернета (например, твит). У меня также есть пул классов для новых данных с сервера каждые 2 минуты, и, поскольку у сервера были новые данные, я обновил информацию о базе данных. Я не буду использовать шаблон делегата для прослушивания изменений БД, потому что у меня так много диспетчеров отображения, которые отображают данные, и это будет очень плохой дизайн, что делает делегат массивом и циклом для передачи данных для каждого контроллера вида. Таким образом, в этом конкретном сценарии лучше всего опубликовать уведомление, сообщающее каждому VC о появлении новых данных.

Если ваш VC удаляет делегата, когда представление исчезает, только текущее получит уведомление и обновит содержимое отображения.

Очевидно, вы могли бы обновить содержимое других VC перед отображением, например, на viewWillAppear:, но при этом содержимое VC будет обновляться не только при необходимости, но и каждый раз, когда вы меняете вкладки.

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