从UITabBarController多次调用NSNotification

Blu*_*ear 2 objective-c uitabbarcontroller nsnotificationcenter ios

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

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

我正在使用的对象实现类型要求我使用NSNotification,因此无法更改交互方式。

编辑:

viewDidLoad方法位于我的选项卡栏中4个VC的顶级VC上。它们全部4个都直接使用它或从中继承。

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

动作处理程序:

- (void) didSelectItemFromCollectionView:(NSNotification *)notification
{
    NSDictionary *cellData = [notification object];

    if (cellData)
    {
        NewVC *pushToVC = [self.storyboard instantiateViewControllerWithIdentifier:@"PushToVC"];

        [self.navigationController pushViewController:pushToVC animated:YES];
    }
}
Run Code Online (Sandbox Code Playgroud)

4个VC中的每一个都是a,UITableViewController并且具有带有可按下对象的单元格。此NSNotificationCenter操作使操作得以执行。

sta*_*Man 5

您必须已经实现了NSNotificationCenter-addObserver:selector:name:object:该方法-viewDidLoad的每viewController

例:

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

相反,有这个在-viewDidLoad,中移动它-viewWillAppear和实施removeObserver:name:object:-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];
}
Run Code Online (Sandbox Code Playgroud)
- (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];
    //                 }];
}
Run Code Online (Sandbox Code Playgroud)

编辑:

您(@Jonathan)评论:

非常感谢您的回答,它对我有很大帮助!实际上,我遇到了发生此问题的另一种情况,但不确定如何解决。现在,我有一个VC,以模式方式呈现了另一个VC。每个人都有相同的NSNotification观察者。当我进入模态呈现的VC时,一切都运行良好,但是一旦我关闭该VC并返回到基础VC,我就会遇到相同的问题,即多次调用该通知。在这种情况下,您有解决方案的想法吗?

现在...关于这个...

首先...注意:

  1. Multiple -addObserver:selector:name:object:将多次注册指定的通知(意味着...同一通知被注册N次将调用N次调用目标选择器
  2. 呈现视图控制器(称之为儿童,比如说,从)母公司 viewController调用-viewWillDisappear:
    那里为...
  3. 驳回儿童 viewController仍然会调用-viewWillAppear:该的

这会在逻辑上造成不平衡,并且如果不加以处理(按照上述doSomething方法的代码示例中的注释行),则会导致Parent多次注册通知(因为该-viewWillAppear:方法经常被调用-viewWillDisappear:

另请参阅:类似问题