RemoveObserver с NSNotification... что я делаю неправильно?
В принципе, у меня есть view1, который в какой-то момент вызывает view2 (через presentModalViewController:animated:
). Когда нажата некоторая UIButton
в view2, view2 вызывает метод уведомления в представлении1 и сразу же после этого отклоняется. В методе уведомления появляется предупреждение.
Метод уведомления работает нормально и называется соответствующим образом. Проблема заключается в том, что каждый раз, когда создается view1 (должно существовать только одно представление1), я предположительно создаю еще один NSNotification
, потому что, если я перехожу из view0 (меню) в view1, а затем назад и вперед несколько раз, Я получаю серию одного и того же предупреждающего сообщения один за другим из метода уведомления столько раз, сколько я открыл view1.
Вот мой код, пожалуйста, скажите мне, что я делаю неправильно:
View1.m
-(void) viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showAlert:)
name:@"alert"
object:nil];
}
-(void) showAlert:(NSNotification*)notification {
// (I've also tried to swap the removeObserver method from dealloc
// to here, but it still fails to remove the observer.)
// < UIAlertView code to pop up a message here. >
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
View2.m
-(IBAction) buttonWasTapped {
[[NSNotificationCenter defaultCenter] postNotificationName:@"alert"
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
Ответы
Ответ 1
Вызов -dealloc
не выполняется автоматически после того, как диспетчер просмотра отклонен - все еще может остаться какая-то "жизнь" в жизни контроллера. В течение этого времени контроллер этого представления все еще подписан для этого уведомления.
Если вы удалите наблюдателя в -viewWillDisappear:
или -viewDidDisappear:
, это будет иметь более непосредственный эффект:
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"alert"
object:nil];
}
Ответ 2
Если вы выполняете удаление Observer в viewWillDisappear:
или viewDidDisappear:
, вы не должны оставлять добавление наблюдателя в viewDidLoad
.
Вместо этого добавьте наблюдателя в viewWillAppear:
. Проблема, с которой вы сталкиваетесь, заключается в том, что когда на экране UIViewController
отображается какое-либо представление, произойдет удаление вашего наблюдателя, и поскольку вы добавили наблюдателя в viewDidLoad
, который произойдет только один раз, он будет потерян.
Имейте в виду, что этот подход хорошо подходит для объектов, которые вы не хотите наблюдать, пока ваш основной вид не находится в переднем фронте.
Также помните, что viewDidUnload
также обесценился.
Ответ 3
В dealloc
нет ничего плохого, если положить removeObserver:
. Просто тот факт, что он не вызвал, означает view1, который неправильно освобождается после отклонения. Похоже, что что-то держит указатель на ваш view1, проверяет наличие циклов сохранения.
Кроме того, вы не должны вызывать dealloc для супер.