removeObserver не работает

У меня есть следующий код:

@implementation SplashViewVC

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.splashView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Default.png"]];
    self.activityIndicator.originY = 355.f;
    [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
        NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];        
        [self.activityIndicator stopAnimating];
        if (errorCode == ERROR_CODE_NO_CONNECTION) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil];
            [alertView show];
        } else if (errorCode == 0) {
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }];
    [self downloadData];
}

- (void)downloadData
{
    [self.activityIndicator startAnimating];
    [[Server sharedServer] getMovieData];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [self downloadData];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super viewDidDisappear:animated];
}

@end

Поэтому я ставлю точки останова в началеviewDidLoad метод, вviewDidDisappear, Когда я запускаю приложение, которое сначала идет вviewDidload, после загрузки это перейти к.viewDidDisappear

Но во время моего приложения я снова загружаю данные и публикуюnotification: NSDownloadComplete, И в этом VC это работа, но я удалил позже, используя:

[[NSNotificationCenter defaultCenter] removeObserver:self]

Это ВК использоватьviewDidLoad однажды в начале & не могу снова добавитьObserver.

Что случилось?

РЕДАКТИРОВАТЬ Я пытаюсь поставить метод addObserverviewWillAppear или жеviewWillDisappear - Нет результатов. я добавитьNSLog(@"addObserver"); до

 [[NSNotificationCenter defaultCenter] addObserverForName...

в viewDidLoad

и писать

- (void)viewDidDisappear:(BOOL)animated
{
    NSLog(@"removeObserver");
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super viewDidDisappear:animated];
}

В журнале вижу:

2013-06-10 14:32:05.646 myApp[9390:c07] addObserver
2013-06-10 14:32:06.780 myApp[9390:c07] removeObserver

Что не так?

РЕДАКТИРОВАТЬ 2 вы можете видеть, что наблюдатель должен быть удален, но он снова запускает блок в методе addObserver

 LE SANG10 июн. 2013 г., 13:40
Только удалить Observer в dealloc
 HAS10 июн. 2013 г., 13:32
Извините, но это нет быть;) фигурная скобка послеself.activityIndicator.originY = 355.f; неправильно. Удалить и тыбудет иметь действующий код;)
 user221327110 июн. 2013 г., 13:38
@ Я редактирую, ошибка, извините
 user221327110 июн. 2013 г., 13:27
@ Все работает нормально, кроме моего вопроса =)
 HAS10 июн. 2013 г., 13:24
Это копия кода ивставили? Мне просто интересно, потому что вашviewDidLoad это всего 3 строки и после этого есть операторы, которых нет ни в одном методе. Тот'не действует;)

Ответы на вопрос(3)

который вы используете, неверен. Вы должны добавить наблюдателя вviewDidAppear: и удали его.viewDidDisappear:

 Jonathan Cichon10 июн. 2013 г., 13:27
или добавить наблюдателя вviewWillAppear:
 user221327110 июн. 2013 г., 13:33
@ e1985 не делайТ помочь. И viewWillAppear: don 'тоже не поможет
Решение Вопроса

которые не сбалансированы должным образом, как отмечалось в других ответах, существует еще одна проблема.

Ваш код для удаления наблюдателя неверен. Для блочного наблюдателявозвращаемое значение изaddObserver должны быть приведены в качестве аргументаremoveObserver, Таким образом, вы должны добавить свойство

@property(nonatomic, strong) id observer;

к классу. Затем вы добавляете наблюдателя с

self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
    // ...
}];

и удалите его с

[[NSNotificationCenter defaultCenter] removeObserver:self.observer];
 user221327110 июн. 2013 г., 14:13
Да, это решит мою проблему. Спасибо =)
 Wilson21 июн. 2016 г., 17:24
Большое вам спасибо, Мартин, ваше решение работает так хорошо.

addObserver а такжеremoveObserver звонки не сбалансированы должным образом.viewDidLoad вызывается только один раз после инициализации VC, ноviewDidDisappear вызывается каждый раз, когда контроллер представления перемещается за пределы экрана.

Чтобы решить вашу проблему, вы должны сбалансировать свойaddObserver а такжеremoveObserver звонки, либо сделав их вviewDidLoad а другой вdeallocили - как предложил e1985 - вviewDidAppear: а также .viewDidDisappear:

РЕДАКТИРОВАТЬИтак, ваша проблема связана с тем, что вы используетеaddObserverForName:object:queue:usingBlock: которые не регистрируютсяself в качестве наблюдателя (какaddObserver:selector:name:object: будет делать, если вы пройдетеself в качестве первого аргумента).

Так что в вашем случае,[[NSNotificationCenter defaultCenter] removeObserver:self]; ничего не делает, потому чтоself не наблюдатель. Вы должны вместо этого позвонитьremoveObserver: на возвращаемое значениеaddObserverForName:object:queue:usingBlock:, как показанов документе:

Возвращаемое значение

Непрозрачный объект, чтобы действовать в качестве наблюдателя.

Итак, ваш код должен выглядеть примерно так:

// header file .h
@interface SplashViewVC : UIViewController

@property (strong, nonatomic) id downloadCompleteObserver;

@end

// implementation file .m
@implementation SplashViewVC

- (void)viewDidLoad
{
    [super viewDidLoad];

    // [...] snip

    self.downloadCompleteObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
        NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];        
        [self.activityIndicator stopAnimating];
        if (errorCode == ERROR_CODE_NO_CONNECTION) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil];
            [alertView show];
        } else if (errorCode == 0) {
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }];
    [self downloadData];
}

// [...] snip

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self.downloadCompleteObserver];
    [super dealloc];
}

@end
 Guillaume Algis10 июн. 2013 г., 13:44
Пожалуйста, объясните проблему более четко тогда. Что такое "не работает" ?
 user221327110 июн. 2013 г., 14:15
спасибо, извините, но я рад, что Мартин Р еще
 user221327110 июн. 2013 г., 13:52
Я добавляю экран, где вы можете увидеть этот блок, вызванный после метода removeObserver.
 Guillaume Algis10 июн. 2013 г., 14:11
хорошо, я думаю, что нашел проблему. см. мое редактирование
 user221327110 июн. 2013 г., 13:43
Я двигаюсь в viewDidAppear: и никаких результатов = (

Ваш ответ на вопрос