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] 

这个VC一开始就使用viewDidLoad一次,不能再addObserver。

哪里不对?

编辑我尝试把addObserver方法viewWillAppearviewWillDisappear – 没有结果。 我添加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方法块

在这里输入图像说明

除了添加/删除观察者呼叫不正确的平衡,在其他答案中指出,还有另一个问题。

您的代码删除观察员是错误的。 对于基于块的观察者,必须将addObserver返回值作为addObserver参数。 所以你应该添加一个属性

 @property(nonatomic, strong) id observer; 

去上课。 然后你添加观察者

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

并删除它

 [[NSNotificationCenter defaultCenter] removeObserver:self.observer]; 

e1985试图公开的是,你的addObserverremoveObserver调用没有适当的平衡。 viewDidLoad在VC初始化后仅被调用一次,但每当视图控制器移出屏幕时,都会viewDidDisappear

为了解决你的问题,你必须平衡你的addObserverremoveObserver调用,或者在viewDidLoad ,另一个在dealloc ,或者 – 如e1985build议的 – 在viewDidAppear:viewDidDisappear:

编辑 :好的,所以你的问题来自于你使用addObserverForName:object:queue:usingBlock:的事实addObserverForName:object:queue:usingBlock:它不会注册self作为观察者(如addObserver:selector:name:object:如果你传递self作为第一个参数) 。

所以在你的情况下, [[NSNotificationCenter defaultCenter] removeObserver:self]; 什么都不做,因为self不是观察者。 您应该调用removeObserver:addObserverForName:object:queue:usingBlock:的返回值,如doc中所示:

返回值

作为观察者的不透明物体。

所以你的代码应该看起来像这样:

 // 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 

您使用的模式不正确。 您应该在viewDidAppear:添加观察者viewDidAppear:并将其在viewDidDisappear:删除viewDidDisappear: