如何阻止NSNotification中的Observer调用两次?

Azh*_*har 52 iphone objective-c nsnotifications ios

我有一个观察者NSNotification被叫两次.我不知道该怎么做.

我用谷歌搜索但没有找到解决方案.

[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(connectedToServer:) name:@"ConnectedToServer" object:nil];

- (void)connectedToServer:(NSNotification*)notification {

    [[NSNotificationCenter defaultCenter] postNotificationName:@"SendMessageToServer" object:message];
}
Run Code Online (Sandbox Code Playgroud)

Emp*_*ack 125

解决方案1:首先要检查通知本身是否发布了两次.

解决方案2:即使通知仅发布一次,也会在您添加通知的观察者(无论通知是否相同)时多次调用该操作.例如,以下两行将self为同一通知(aSelector)注册observer ()两次.

[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
Run Code Online (Sandbox Code Playgroud)

您必须找到第二次添加观察者的位置,然后将其删除.并且还要确保您添加观察者的代码不会被调用两次.

解决方案3:如果您不确定是否已添加观察者,则只需执行以下操作即可.这将确保观察者只添加一次.

[[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了所有三种解决方案,但没有工作:( (18认同)
  • [[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil]; 是最好的答案 (9认同)
  • 解决方案3给了我类似问题的提示.谢谢! (4认同)
  • 也许你收到两次通知.检查它在`aSelector`中设置断点并查看调用堆栈. (2认同)
  • 与**Azhar**一样,我无法使用上述方法解决此问题.不确定发生了什么 - 但在我的情况下,我转而使用`delegate`来满足我的回调需求.这不是所有案例的解决方案,而是一种可能有助于未来读者陷入困境的解决方法. (2认同)
  • 我从解决方案 3 中得到了解决方案。我已经在视图中实现了此方法 [NSNotificationCenter defaultCenter] 并在类中两次调用了视图确实加载。 (2认同)

tfr*_*377 16

如果您的addObserver方法多次运行,它将创建多个观察者.我的问题是,viewWillAppear在我发布通知之前,我以某种方式将我的观察者放置在其中多次出现,这导致我的观察者被多次调用.

虽然EmptyStack的第3个解决方案有效,但有一个原因是你的观察者被调用两次,所以通过找到它,你可以防止不必要的代码行,而不是删除和添加相同的观察者.

我建议让你的观察者进入,viewDidLoad以避免像我经历的那样的简单错误.


bha*_*esh 7

尝试在viewWillDisappear方法中删除Observer:

-(void)viewWillDisappear:(BOOL)animated{

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"startAnimating" object:nil]; }
Run Code Online (Sandbox Code Playgroud)