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

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];
}
4b9b3361

Ответ 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 для супер.