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的想法吗?
现在…关于这个…
首先…注意:
- 多个
-addObserver:selector:name:object:
将多次注册指定的通知( 意味着…相同的通知被注册N次将调用目标select器N次 ) - 从父
viewController
呈现一个ViewController(称之为Child )将不会调用父viewController
的-viewWillDisappear:
在哪里… - 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]; });