Наблюдатель никогда не удаляется из NSNotificationCenter

Я добавляю контроллер представления в качестве наблюдателя для уведомления UIKeyboardWillShowNotification.

У меня есть этот код в моем viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self
                                     selector:@selector(keyboardWillShow:)
                                         name:UIKeyboardWillShowNotification
                                       object:nil];

И в моем dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self];

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

Я видел несколько вопросов здесь, в StackOverflow, об этой конкретной проблеме, но ни один из ответов не работает для меня.

Я пытался удалить наблюдателя в viewWillDisappear и viewDidDisappear, но возникает та же проблема.

Я использую АРК.


person Hesham    schedule 23.08.2013    source источник
comment
не используйте Dealloc с ARC   -  person Vaibhav Gautam    schedule 23.08.2013
comment
@Вайбхав ошибается. Использование dealloc — это хорошая практика, вы просто не можете вызывать [super dealloc] в реализации.   -  person Gabriele Petronella    schedule 23.08.2013
comment
у меня та же проблема, что и у вас, но я не могу найти правильного решения, поэтому я исправил эту проблему с помощью BOOL isFirstTime;, установил YES, когда keyboardWillShow и - (void)keyboardDidHide { if(!isFirstTime) return; , , , , , , isTxtFieldKeyBoard = NO; isFirstTime = НЕТ; }   -  person iPatel    schedule 23.08.2013
comment
@GabrielePetronella: спасибо, что просветили меня :)   -  person Vaibhav Gautam    schedule 23.08.2013


Ответы (4)


Вы пробовали именно этот фрагмент кода в viewWillDisappear?

- (void)viewWillDisappear:(BOOL)animated 
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

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

person Segev    schedule 23.08.2013
comment
Да, как я уже упоминал в своем вопросе, я пробовал. Я сделал это без вызова super, но это не имеет значения, поскольку реализация по умолчанию ничего не делает. Я попробовал то, что вы предложили здесь, открыв контроллер представления один раз, закрыв его, а затем открыв другой контроллер представления, который имеет UITextField. Как только появилась клавиатура, приложение вылетело с сообщением *** -[NewTrackerViewController respondsToSelector:]: message sent to deallocated instance 0xc14ac40. NewTrackerViewController никогда не отменяет регистрацию в качестве наблюдателя. - person Hesham; 23.08.2013

Возможно, попробуйте указать параметр name, который вы установили ранее, следующим образом:

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
person zbMax    schedule 23.08.2013

Похоже, наблюдатель устанавливается несколько раз. Ваш контроллер унаследован от класса, который также регистрируется для того же уведомления? Это может привести к тому, что экземпляр контроллера будет зарегистрирован как наблюдатель более одного раза. В качестве обходного пути попробуйте это, в вашем классе контроллера, где вы добавляете наблюдателя,

// Remove as observer first
[[NSNotificationCenter defaultCenter] removeObserver:self];
                                      name:UIKeyboardWillShowNotification
                                      object:nil];
// Then add
[[NSNotificationCenter defaultCenter] addObserver:self
                                      selector:@selector(keyboardWillShow:)
                                      name:UIKeyboardWillShowNotification
                                      object:nil];

Это гарантирует, что наблюдатель будет добавлен только один раз.

Надеюсь, это поможет!

person Amar    schedule 23.08.2013

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

он отлично работает со мной

person MhammedMohie    schedule 23.08.2013