为什么我的NSNotification会多次调用它的观察者?

Bar*_*K88 25 iphone nsnotifications uiviewcontroller nsnotificationcenter ios

在App中,我使用了几个viewcontrollers.在一个viewcontroller上,一个观察者初始化如下:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MyNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMethod:) name:@"MyNotification" object:nil];
Run Code Online (Sandbox Code Playgroud)

即使NSNotification在初始化之前移除了执行次数,myMethod:也可以通过相应视图控制器上的重复视图量来总结.

为什么会发生这种情况?如何避免myMethod:被调用一次以上.

注意:我通过使用断点确保多次调用postNotification时没有犯错.

编辑:这就是我的postNotification的样子

NSArray * objects = [NSArray arrayWithObjects:[NSNumber numberWithInt:number],someText, nil];
NSArray * keys = [NSArray arrayWithObjects:@"Number",@"Text", nil];
NSDictionary * userInfo = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:self userInfo:userInfo];
Run Code Online (Sandbox Code Playgroud)

编辑:甚至在我订阅了viewwillappear之后:我得到了相同的结果.myMethod:被多次调用.(我重新加载viewcontroller的次数).

-(void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"MyNotification" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMethod:) name:@"MyNotification" object:nil];
}
Run Code Online (Sandbox Code Playgroud)

编辑:我的生命周期似乎有些问题.ViewDidUnload和dealloc没有被调用,但是viewdiddisappear被调用.

我将Viewcontroller推送到堆栈的方式如下,其中parent是tableview子类(单击此viewcontroller启动的行:

detailScreen * screen = [[detailScreen alloc] initWithContentID:ID andFullContentArray:fullContentIndex andParent:parent];
[self.navigationController pushViewController:screen animated:YES];
Run Code Online (Sandbox Code Playgroud)

解:

将nsnotification移除到viewdiddisappear就可以了.感谢您的指导!

小智 37

您在哪些方法中注册观察员?

Apple建议观察员应注册viewWillAppear:并注册viewWillDissapear:

你确定你没有两次注册观察员吗?


Jaa*_*nus 35

根据此描述,可能的原因是您的viewcontrollers被过度保留,并且在您认为它们时不会被释放.如果事情被过度保留,即使使用ARC,这也很常见.因此,您认为您只有一个给定viewcontroller的实例处于活动状态,而您实际上有几个实时实例,并且它们都会监听通知.

如果我遇到这种情况,我会在viewcontroller的dealloc方法中放置一个断点,并确保它正确解除分配,如果这是你的应用程序的预期设计.


小智 5

在快速运行的应用程序中遇到了这个问题。该应用程序在首次启动时收到一次通知。该通知会增加您进入后台并返回的次数。IE

  • 应用程序启动一个 - 添加观察者在视图中出现或视图加载后被调用一次 - 通知被调用一次
  • 应用程序进入后台并返回,添加观察者在视图将出现或视图已加载时再次被调用。通知被调用两次。
  • 该数字会增加您进入后台并返回的次数。
  • 视图中的代码将消失不会产生任何影响,因为视图仍在窗口堆栈中并且尚未从中删除。

解决方案:观察应用程序将在视图控制器中重新激活:

  NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationWillResign:", name: UIApplicationWillResignActiveNotification, object: nil)

  func applicationWillResign(notification : NSNotification) {
    NSNotificationCenter.defaultCenter().removeObserver(self)
  }
Run Code Online (Sandbox Code Playgroud)

这将确保当视图进入后台时,您的视图控制器将删除通知的观察者。