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

Удаление наблюдателя NSNotificationCenter в iOS 5 ARC

У меня есть проект на основе iOS 5 ARC, и у меня возникают трудности с тем, где я должен удалить наблюдателя для наблюдений NSNotificationCenter, которые я зарегистрировал в пределах UIViewController. Аналогичные сообщения на SO сказали, что это должно быть сделано в методе -dealloc. Хотя этот метод не требуется в проектах ARC, я добавил его со следующим кодом:

- (void)dealloc {

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}

В качестве теста я открываю UIViewController (в пределах UINavigationController), делаю некоторые действия, которые вызывают уведомления, а затем выталкивает их из стека, нажимая кнопку "Назад". Затем я снова открываю UIViewController и делаю еще кое-что для запуска уведомлений, но обратите внимание, что каждый обратный вызов вызывается дважды - указание на то, что предыдущие уведомления не были отменены. Повторение этой процедуры просто вызывает вызов каждого обратного вызова более чем раз, поэтому они, похоже, никогда не будут отменять регистрацию.

Любая помощь будет оценена!

4b9b3361

Ответ 1

Довольно ясно, что ваш метод dealloc не вызывается (и не является вызовом removeObserver).

Почему бы не удалить наблюдателя UIViewController в методах viewDidUnload: или viewWillDisappear:?

Ответ 2

Если ваш dealloc не вызывается, вероятно, потому, что кто-то все еще держит ссылку на контроллер вида. Возможно, вам нужно отметить что-то как __weak? Вы можете использовать инструмент распределения, чтобы отслеживать, что удерживает ваш контроллер.

Ответ 3

"Мне также нужны обратные вызовы уведомлений, которые все еще будут запущены, если представление за пределами экрана" → вам может потребоваться зарегистрировать UIApplicationWillEnterForegroundNotification. Если да, попробуйте это:

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"viewWillAppear");
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidEnterBackground:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"viewWillDisappear");
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    NSLog(@"applicationWillEnterForeground");
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidEnterBackground:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    // do your stuff here
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"applicationDidEnterBackground");
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationWillEnterForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];
}

Идея заключается в добавлении или удалении UIApplicationDidEnterBackgroundNotification при каждом входе и выходе из экрана. Мы просто регистрируем UIApplicationWillEnterForegroundNotification, когда приложение вводит фон и удаляет его обратно. Обратите внимание, что мы просто удаляем UIApplicationDidEnterBackgroundNotification, когда viewWillDisappear.

Мой dealloc() не вызван каким-то образом, поэтому я нашел этот способ, надеюсь, он будет полезен и вам.

Наслаждайтесь:)