Удалить Observer с NSNotification... что я делаю не так?
По сути, у меня есть view1, который в какой-то момент вызывает view2 (через presentModalViewController:animated:
). Когда определенный UIButton
в view2 нажата, view2 вызывает метод уведомления в view1 и сразу после этого закрывается. Метод уведомления выскакивает предупреждение.
Метод уведомления работает нормально и вызывается соответствующим образом. Проблема в том, что каждый раз, когда создается view1 (только один view1 должен существовать одновременно), я, вероятно, получаю другой 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];
}
3 ответа
Призвание -dealloc
не происходит автоматически после того, как контроллер представления уволен - все еще может быть некоторая "жизнь" в жизни контроллера представления. В тот период времени этот контроллер представления все еще подписан на это уведомление.
Если вы удалите наблюдателя в -viewWillDisappear:
или же -viewDidDisappear:
, это будет иметь более непосредственный эффект:
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"alert"
object:nil];
}
Если вы реализуете удаление Observer в viewWillDisappear:
или же viewDidDisappear:
тогда вам не следует оставлять добавление наблюдателя в поле viewDidLoad
,
Вместо этого добавьте наблюдателя в поле viewWillAppear:
, Проблема, с которой вы столкнулись, заключается в том, что когда на UIViewController
просмотреть удаление вашего наблюдателя произойдет, и так как вы добавили наблюдателя в viewDidLoad
что произойдет только один раз, он будет потерян.
Имейте в виду, что этот подход хорошо работает для объектов, которые вы не хотите наблюдать, пока ваш основной вид не находится на переднем плане.
Также имейте в виду, что viewDidUnload
был также амортизирован.
В этом нет ничего плохого removeObserver:
в dealloc
, Тот факт, что он не называется, означает, что view1 не будет правильно освобожден после увольнения. Похоже, что-то содержит указатель на ваш view1, проверьте, чтобы сохранить циклы.
Кроме того, вы не должны вызывать Deloc на супер.