удалитьObserver с NSNotification ... что я делаю не так? - PullRequest
27 голосов
/ 25 июля 2010

По сути, у меня есть view1, который в какой-то момент вызывает view2 (через presentModalViewController:animated:). Когда определенная UIButton в view2 нажата, view2 вызывает метод уведомления в view1 и сразу после этого отклоняется. Метод уведомления выскакивает предупреждение.

Метод уведомления работает нормально и вызывается соответствующим образом. Проблема в том, что каждый раз, когда создается view1 (за один раз должен существовать только один view1), я, вероятно, получаю еще один созданный NSNotification, потому что если я перейду из view0 (меню) в view1, то назад и вперед несколько раз, Я получаю серию одного и того же предупреждающего сообщения, одно за другим, из метода уведомления столько раз, сколько открывал представление1.

Вот мой код, скажите, пожалуйста, что я делаю не так:

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 ]

60 голосов
/ 25 июля 2010

Вызов -dealloc автоматически не происходит после того, как контроллер представления уволен - все еще может оставаться некоторая «жизнь» в жизни контроллера представления.В тот период времени этот контроллер представления все еще подписан на это уведомление.

Если вы удалите наблюдателя в -viewWillDisappear: или -viewDidDisappear:, это будет иметь более немедленный эффект:

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:@"alert" 
                                                  object:nil];
}
6 голосов
/ 19 июня 2013

Если вы реализуете удаление Обозревателя в viewWillDisappear: или viewDidDisappear:, то не следует оставлять добавление наблюдателя в viewDidLoad.

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

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

Также имейте в виду, что viewDidUnload устарелтоже.

2 голосов
/ 25 января 2014

Нет ничего плохого в том, чтобы поставить removeObserver: в dealloc.Тот факт, что он не называется, означает, что view1 не будет правильно освобожден после увольнения.Похоже, что-то содержит указатель на ваш view1, проверьте, не сохранились ли циклы.

Кроме того, вы не должны вызывать dealloc на super.

...