Удаление обозревателя NSNotificationCenter в iOS 5 ARC - PullRequest
21 голосов
/ 04 декабря 2011

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

- (void)dealloc {

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}

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

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

7 голосов
/ 04 декабря 2011

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

7 голосов
/ 04 декабря 2011

Совершенно очевидно, что ваш dealloc метод не вызывается (равно как и вызов removeObserver).

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

3 голосов
/ 12 сентября 2012

«Мне также нужно, чтобы обратные вызовы уведомлений все еще запускались, если представление находится за пределами экрана» -> вам может потребоваться зарегистрировать 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 () каким-то образом не вызывается, поэтому я нашел этот способ, надеюсь, он вам пригодится.

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

...