#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, безопасно ли это?