Предупреждение для пользователей iOS / iPhone о дублирующих наблюдениях NSNotification - PullRequest
22 голосов
/ 19 июня 2010

Это не столько вопрос, сколько предупреждение другим, чтобы сэкономить им время.

NSNotificationCenter на iOS 3 / iPhone OS 3 (я полагаю, также Mac OS X и iOS 4) имеет следующее поведение:

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

Это почти никогда не то поведение, которое вы хотите увидеть, и почти всегда случайное.

Пример:

Я хочу, чтобы мой контроллер вида получал уведомления от одноэлементного сетевого объекта при поступлении новых данных:

- (void) viewDidLoad 
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(newDataArrived:) 
                name:NewDataArrivedNotification
              object:[NetworkListener sharedNetworkListener]];
}

но раньше я уже поместил то же самое в viewWillAppear:

- (void) viewWillAppear
{
    [super viewWillAppear];

    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(newDataArrived:)
                name:NewDataArrivedNotification
              object:[NetworkListener sharedNetworkListener]];
}

Обратите внимание, что это точно то же самое уведомление с разрешением на одного и того же наблюдателя, отправителя и имя уведомления.

В этом случае, если я не удалю один из этих вызовов addObserver, я получу дубликаты уведомлений на мой контроллер представления.

В многопоточной среде это мир боли. Поверь мне.

Просто выкладываю это на случай, если есть другие, которые сталкиваются с чем-то вроде этого.

Ответы [ 3 ]

4 голосов
/ 21 апреля 2013

NSNotificationCenter на iOS 3 / iPhone OS 3 (я полагаю, также Mac OS X и iOS 4) имеет следующее поведение:

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

Это почти никогда не то поведение, которое вы хотите увидеть, и оно почти всегда случайное.

Пример:

Я хочу, чтобы мой контроллер вида получал уведомления от одноэлементного сетевого объекта, когда поступают новые данные:

- (void) viewDidLoad 
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(newDataArrived:) 
                name:NewDataArrivedNotification
              object:[NetworkListener sharedNetworkListener]];
}

но раньше я уже поместил то же самое в viewWillAppear:

- (void) viewWillAppear
{
    [super viewWillAppear];

    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(newDataArrived:)
                name:NewDataArrivedNotification
              object:[NetworkListener sharedNetworkListener]];
}

Обратите внимание, что это точно то же самое уведомление, разрешающее к одному и тому же наблюдателю, отправителю и имени уведомления.

В этом случае, если я не удалю один из этих вызовов addObserver, я получу дубликаты уведомлений на мой контроллер представления.

В многопоточной среде это мир боли. Поверь мне.

Просто выкладываю это на случай, если есть другие, которые сталкиваются с чем-то вроде этого.

2 голосов
/ 24 января 2013

Вы должны и всегда очищать своих наблюдателей.Самый простой способ сделать это: [[NSNotificationCenter defaultCenter] removeObserver: self]viewDidLoad не подходит для добавления наблюдателей, потому что эти функции могут вызываться несколько раз, это происходит при запуске viewDidUnload.Хорошее место для размещения ваших addObservers в viewWillAppear и удаленияObservers в viewWillDisappear.

0 голосов
/ 29 декабря 2012

Как вы сказали сами, NSNotificationCenter не проверяет наличие дубликатов, что может раздражать некоторых, но имеет смысл при выборе всей системы, стоящей за ним.

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

Спасибо за понимание и за хорошее, оптимизированное для SEO предупреждение:)

...