Удаление всего наблюдателя уведомлений из одного места

#ios #objective-c #iphone #cocoa-touch

#iOS #objective-c #iPhone #cocoa-touch

Вопрос:

Я хочу удалить наблюдателя уведомлений, и я использую метод:

 [[NSNotificationCenter defaultCenter] removeObserver: name:@"myNotification" object:nil];
  

для этого. Теперь есть много наблюдателей, которые прослушивают это уведомление, и я хочу удалить их всех одним выстрелом из централизованного места. Могу ли я передать ‘nil’ в первом параметре, и это удалит всех наблюдателей, которые прослушивают myNotification?

Ответ №1:

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

 [[NSNotificationCenter defaultCenter] removeObserver:self];
  

Это на объекте level…so он отменит регистрацию для многих уведомлений. Он не отменит регистрацию для одного уведомления во многих объектах.

Надеюсь, я правильно понял ваш вопрос.

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

1. ОК. Нет ли способа отменить регистрацию объекта из другого объекта? Я принадлежу к классу A и хочу отменить регистрацию объекта класса B в уведомлении.

2. Я не думаю, что это то, что имел в виду @Abhinav. Он хочет удалить всех наблюдателей из таблицы отправки NSNotificationCenter, а не требовать, чтобы конкретный объект останавливал наблюдателя всех уведомлений.

3. @xjones Я перечитал, и вы правы. Я прочитал ‘first parameter’ как имя уведомления, а не объекта. При этом, как говорится, не существует способа удалить всех наблюдателей конкретного уведомления (как, похоже, мало кто заявлял). Просто нужно сделать это в каждом классе, который регистрируется.

Ответ №2:

В случае Swift вы делаете это следующим образом:

 NSNotificationCenter.defaultCenter().removeObserver(self)
  

И в Swift 3:

 NotificationCenter.default.removeObserver(self)
  

Ответ №3:

К сожалению, нет способа удалить всех наблюдателей определенного уведомления в одном месте. Хотя, безусловно, бывают случаи, когда это было бы неплохо, делать это было бы опасно, как правило, объект, выполняющий наблюдение, должен отвечать за добавление и удаление самого себя в качестве наблюдателя конкретного уведомления. Это гарантирует отсутствие непредсказуемого поведения, наблюдатели b / c могут приходить и уходить, поэтому они настраивают и убирают за собой.

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

[РЕДАКТИРОВАТЬ: ОТВЕТ НА ВАШ КОММЕНТАРИЙ О ТОМ, ЧТО КЛАСС B ПРЕКРАЩАЕТ НАБЛЮДЕНИЕ КЛАССА A]

Я только что увидел ваш комментарий. Существуют разные способы добиться этого, особенно если класс B знает о классе A. Когда вы ссылаетесь на классы, звучит так, как будто вы хотите повлиять на все экземпляры класса по сравнению с конкретным экземпляром. Если у вас есть какое-то условие, которое вы можете проверить при обработке уведомления, вот как я бы подошел к этому. В обработчике уведомлений что-то вроде:

 if ([self shouldRespondToNotificationNamed:notification.name]) {
   [self performNotificationAction];
}
  

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