Подтвердить что ты не робот

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

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

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

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

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

Пример:

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

- (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, я получу дубликаты уведомлений в свой контроллер представления.

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

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

4b9b3361

Ответ 1

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

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

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

Пример:

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

- (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

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

Ответ 3

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

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

Благодарим вас за понимание и за хорошее SEO-предупреждение:)