NSNotification被UITabBarController多次调用

我有一个UITabBarController ,它有4个选项卡。 每个选项卡都是一个单独的UIViewController 。 我有4个VC中的每一个使用NSNotification来对某个对象进行操作。 4个VC都以相同的方式响应通知,因为它是每个页面上的一个类似的对象。 当这个对象被按下时,它将呈现一个视图到当前的视图控制器。 问题是,如果我移动到其他3个选项卡中的任何一个,现在这个视图也在他们的VC上。 这是因为当任何VC被按下时,所有4个选项卡都会响应通知。 我需要它只响应用户当前所在的VC,而不是标签栏中的其他任何人。

有没有办法让这个工作正常? 也许是一个阈值,您可以设置通知调用后可以执行select器的次数? 这样我可以将它设置为1,并且在任何给定的时间,如果该通知被调用,select器只能被称为1次。

我使用的对象实现types要求使用NSNotificatio n,所以无法改变我如何交互。

编辑:

这个viewDidLoad方法是在我的标签栏中的4个VC的顶级VC。 他们四个都是直接使用或inheritance。

 - (void) viewDidLoad { ... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSelectItemFromCollectionView:) name:@"didSelectItemFromCollectionView" object:nil]; } 

行动处理程序:

 - (void) didSelectItemFromCollectionView:(NSNotification *)notification { NSDictionary *cellData = [notification object]; if (cellData) { NewVC *pushToVC = [self.storyboard instantiateViewControllerWithIdentifier:@"PushToVC"]; [self.navigationController pushViewController:pushToVC animated:YES]; } } 

4个VC中的每一个都是一个UITableViewController并且有一个可以被按下的对象。 这个NSNotificationCenter操作是允许操作工作的。

您必须在每个viewController-viewDidLoad中实现了NSNotificationCenter-addObserver:selector:name:object:方法

例:

 - (void)viewDidLoad { //... [NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomething:) name:@"TestNotification" object:nil]; } 

而不是在-viewDidLoad ,在-viewDidLoad中移动它,并实现removeObserver:name:object: in -viewWillDisappear

这样,只有当前的viewController会响应通知。

例:

 - (void)viewWillAppear:(BOOL)animated { //... [NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomething:) name:@"TestNotification" object:nil]; } - (void)viewWillDisappear:(BOOL)animated { //... [NSNotificationCenter defaultCenter] removeObserver:self name:@"TestNotification" object:nil]; } 

 - (void)doSomething:(NSNotification *)userInfo { //... //if you push a viewController then the following is all you need [self.navigationController pushViewController:vcSomething animated:YES]; //however.... if you're instead presenting a viewController modally then //you should implement "-removeObserver:name:object: in this method as well //[NSNotificationCenter defaultCenter] removeObserver:self // name:@"TestNotification" // object:nil]; //[self presentViewController:vcSomething // animated:YES // completion:nil]; //OR... in the completion parameter as: //[self presentViewController:vcSomething // animated:YES // completion:^{ // [NSNotificationCenter defaultCenter] removeObserver:self // name:@"TestNotification" // object:nil]; // }]; } 

编辑:

你(@Jonathan)评论道:

我真的很感谢你的回答,并且帮助了我很多! 我其实遇到了这个问题发生的情况,我不知道如何解决。 现在我有一个风险投资,模式提出另一个VC。 每个人都有相同的NSNotification的观察员。 当我在模态提交的VC中,一切都performance的很好,但是一旦我解散VC并返回到底层的话,我就会遇到同样的问题,即多次调用通知。 在这种情况下你有一个解决scheme的想法吗?

现在…关于这个…

首先…注意:

  1. 多个-addObserver:selector:name:object:将多次注册指定的通知( 意味着…相同的通知被注册N次将调用目标select器N次
  2. viewController呈现一个ViewController(称之为Child )将不会调用 viewController-viewWillDisappear:
    在哪里…
  3. closures viewController仍然会调用Parent的 -viewWillAppear:

这会在逻辑中造成不平衡,如果不处理(按照上面的doSomething方法的代码示例中的注释行),会导致Parent多次注册该通知(因为它的-viewWillAppear:方法被更频繁地调用不是-viewWillDisappear:

也看到: 类似的问题

它只能被调用一次,以免再次被调用

 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(methodName:) name:@"name" object:nil]; });