从UITabBarController多次调用NSNotification [英] NSNotification is being called multiple times from UITabBarController

查看:98
本文介绍了从UITabBarController多次调用NSNotification的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a UITabBarController, which has 4 tabs. Each one of those tabs is a separate UIViewController. I have objects on each one of those 4 VC's that use NSNotification's to perform actions upon the press of a certain object. The 4 VC's all respond to the notification in the same way because it is a similar object on each page. When this object is pressed it presents a view onto the current view controller. The problem is that if I move to any of the other 3 tabs now that view is also on their VC. That is because the notification is being responded to on all 4 tabs when it is pressed on any of the VC's. I am needing it to only respond to the VC that the user is currently on and not any of the others that are in the tab bar.

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

Is there a way to get this to work properly? Maybe a threshold where you can set how many times the notification can perform its selector after being called? That way I could set it to 1 and at any given time if that notification is called the selector can only be called 1 time.

我对象实现的类型m使用要求我使用 NSNotificatio n所以没有办法改变我的交互方式。

The type of object implementation that I'm using requires me to use NSNotification's so there is no way to change how I interact.

编辑:

viewDidLoad 方法已启用我标签栏中4个VC的顶级VC。它们中的所有4个都直接使用它或继承它。

This viewDidLoad method is on the top level VC for the 4 VC's in my tab bar. All 4 of them either use this directly or inherit from it.

- (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 操作允许操作工作。

Each of the 4 VC's is a UITableViewController and have cells with an object that can be pressed. This NSNotificationCenter action is what allows the operation to work.

推荐答案

您必须已实施 NSNotificationCenter -addObserver:selector:name:object:每个 viewController的 -viewDidLoad 中的方法

You must have implemented the NSNotificationCenter's -addObserver:selector:name:object: method in the -viewDidLoad of every viewController

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

而不是在 -viewDidLoad ,在 -viewWillAppear 中移动它,并在 removeObserver:name:object: > -viewWillDisappear 。

Instead of having this in -viewDidLoad, move it within -viewWillAppear and implement removeObserver:name:object: in -viewWillDisappear.

这样,只有 viewController 目前 将回复通知。

This way, only the viewController that is currently on will respond to the notification.

- (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)评论说:

You (@Jonathan) commented:


我真的感谢你的回答,它帮助了我很多!我实际上遇到了这个问题发生的另一个场景,而且我不知道如何解决这个问题。现在我有一个VC,以另一个VC模式提供
。每个人都有相同的
NSNotification观察员。当我在
模态呈现的VC中时,一切都表现得非常好,但是一旦我解雇VC并返回到底层的
,我就会遇到同样的问题,其中通知是
称为多个倍。你对这个
案的解决方案有什么想法吗?

I really appreciate your answer and it has helped me out a lot! I actually ran into one more scenario where this issue occur's and I'm not sure how to figure it out. Right now I have a VC that presents another VC modally. Each one has observers for the same NSNotification. Everything performs perfectly well when I'm in the modally presented VC, but once I dismiss that VC and return to the underlying one I have the same issue where the notification is being called multiple times. Do you have an idea for a solution in this case?

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

Now... regarding this...

首先......注意:


  1. 多个 -addObserver:selector:name:object:将多次注册指定的通知(表示...相同的通知被注册N次将调用目标选择器N时间

  2. 中提出一个ViewController(称之为儿童) viewController NOT 将调用Parent的$ code> -viewWillDisappear:

    b $ b 其中as ...

  3. 解雇儿童 viewController 仍然会调用 -viewWillAppear:

  1. Multiple -addObserver:selector:name:object: will register the specified notification multiple times (means... same notification being registered for N times will call invoke the target selector N times)
  2. Presenting a ViewController (call it Child) from, say, Parent viewController will NOT invoke the -viewWillDisappear: of the Parent
    where as...
  3. Dismissing the Child viewController will still invoke -viewWillAppear: of the Parent

这会造成不平衡逻辑,如果不处理(根据 doSometh的代码示例中的注释行如上所述方法),会导致 Parent 多次注册通知(因为它是 -viewWillAppear:方法被调用的次数通常是 -viewWillDisappear:

This creates an imbalance in the logic and if not handled (as per the commented lines in the code example of the doSomething method above), it results in the Parent registering for the notification multiple times (as it's -viewWillAppear: method is called more often than not -viewWillDisappear:)

另见:类似问题

这篇关于从UITabBarController多次调用NSNotification的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆