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

Я не уверен в точной причине этого (кроме двусмысленности, описанной ниже), но я читал, что несколько наблюдателей не должны добавляться в 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?

person Old McStopher    schedule 08.11.2011    source источник
comment
Что предлагает ваш Вариант 2?   -  person Jim Puls    schedule 08.11.2011
comment
@JimPuls По сути, добавьте селектор и имя к определенной записи в реестре таблиц (без повторного добавления себя в качестве наблюдателя)   -  person Old McStopher    schedule 08.11.2011
comment
Ну да, но это то, что уже делает первый метод. Нет отдельного понятия наблюдателя; скорее, ваш объект указан в таблице с несколькими столбцами.   -  person Jim Puls    schedule 08.11.2011
comment
Это то, что я понял, но не был уверен, как это реализовано, и не хотел, чтобы отправлялись фантомные сообщения или несуществующие наблюдатели.   -  person Old McStopher    schedule 08.11.2011


Ответы (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];
}
person jscs    schedule 08.11.2011
comment
если я зарегистрировал наблюдателя один раз, но дважды удалил его с помощью removeObserver:name:object, безопасно ли это? - person fifth; 01.06.2012

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

удалитьнаблюдателя:

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

- (void)removeObserver:(id)notificationObserver

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

person Jim Puls    schedule 08.11.2011