Добавьте другую пару селектор / имя к существующему наблюдателю в NSNotificationCenter

#iphone #objective-c #cocoa-touch #nsnotifications #nsnotificationcenter

#iPhone #objective-c #cocoa-touch #уведомления о nsnotifications ( нс ) #nsnotificationcenter #nsnotifications

Вопрос:

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

Я добавил первый следующим образом:

 [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(method1:) 
                                             name:@"method1Notification"
                                           object:nil];
  

Вариант 1:

Добавление второго, как показано ниже), похоже, снова добавит « self » в центр уведомлений.

 [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(method2:) 
                                             name:@"method2Notification"
                                           object:nil];
  

Это нормально? Или, при необходимости, есть ли способ просто добавить другую пару селектор / имя к записи « self » в центре уведомлений по умолчанию?


Вариант 2: (псевдокод)

 [[[NSNotificationCenter defaultCenter] mySelfObserver]
                        addSelector:@selector(method2:) 
                               name:@"method2Notification"
                             object:nil];
  

Неоднозначность:

Казалось бы, в любом случае, если бы он был добавлен во второй раз, в dealloc: его, возможно, пришлось бы удалить как наблюдателя дважды?

 [[NSNotificationCenter defaultCenter] removeObserver:self];
// ... REMOVE IT AGAIN IF OBSERVER ADDED TWICE TO NOTIFICATION CENTER?
  

Комментарии:

1. Что предлагает ваш «Вариант 2»?

2. @JimPuls По сути, «добавьте селектор и имя к определенной записи в реестре таблиц» (без повторного добавления «self» в качестве наблюдателя)

3. Ну, конечно, но это то, что уже делает первый метод. Отдельного понятия «наблюдатель» не существует; скорее, ваш объект указан в таблице с несколькими столбцами.

4. Это то, что я понял, но не был уверен, как это было реализовано, и не хотел, чтобы отправлялись призрачные сообщения или несуществующие наблюдатели.

Ответ №1:

Все, что вы опубликовали («Вариант 1»), в порядке. Смотрите документы:

removeObserver:

Удаляет все записи, указывающие данного наблюдателя, из таблицы отправки получателя.

- (void)removeObserver:(id)notificationObserver

Вам просто нужно вызвать removeObserver: один раз; есть отдельный removeObserver:name:object: метод, если вы хотите удалить только одно наблюдение за конкретным уведомлением.

Ответ №2:

Я думаю, вы немного запутались. Совершенно нормально добавлять данного наблюдателя любое количество раз, при условии, что уведомления или объекты отличаются.

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

Вам также нужно вызвать только removeObserver: один раз для любого наблюдателя, независимо от того, сколько вещей он наблюдает.

 - (void)registerForNotifications
{
    NSNotificationCenter * noteCenter = [NSNotificationCenter defaultCenter];
    [noteCenter addObserver:self
                   selector:@selector(keyboardWasShown:)
                       name:UIKeyboardDidShowNotification 
                     object:nil];

    [noteCenter addObserver:self
                   selector:@selector(keyboardWillBeHidden:)
                       name:UIKeyboardWillHideNotification 
                     object:nil];
    // Totally fine up to this point; this object is observing two different
    // notifications.
    // Now, add two different observations for the same notification, but
    // with _different_ objects:
    [noteCenter addObserver:self
                   selector:@selector(fluffyHasReproduced:)
                       name:RabbitsHaveReproducedNotification
                     object:MyRabbitFluffy];
    [noteCenter addObserver:self
                   selector:@selector(luckyHasReproduced:)
                       name:RabbitsHaveReproducedNotification
                     object:MyRabbitLucky];
    // This is fine; the appropriate rabbit notification method will only be
    // called when the corresponding rabbit reproduces.
    // However...
    // This will make luckyHasReproduced: be called _twice_ whenever
    // MyRabbitLucky posts RabbitsHaveReproducedNotification
    [noteCenter addObserver:self
                   selector:@selector(luckyHasReproduced:)
                       name:RabbitsHaveReproducedNotification
                     object:MyRabbitLucky];
    // Further,
    // this is probably not what you want. otherRabbitsHaveReproduced: is
    // going to be called whenever either Fluffy or Lucky post their
    // notifications, too. The nil object acts as a wildcard.
    [noteCenter addObserver:self
                   selector:@selector(otherRabbitsHaveReproduced:) 
                       name:RabbitsHaveReproducedNotification 
                     object:nil];

}
  

Позже, когда это будет необходимо ( viewWillDisappear: или viewDidUnload: для контроллеров просмотра, в зависимости от характера уведомлений; dealloc для других объектов):

 - (void) unregisterForNotifications {
    // Clear out _all_ observations that this object was making
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
  

Комментарии:

1. если я зарегистрировал наблюдателя один раз, но дважды удалил его с помощью removeObserver:name:object, безопасно ли это?