【问题标题】:"Pushing the same view controller instance more than once is not supported" exception“不支持多次推送同一个视图控制器实例”异常
【发布时间】:2011-10-28 07:52:20
【问题描述】:

我正在使用以下代码检索一些邮件并将它们放入我的收件箱。

MyInboxVC *inboxVC=[MyInboxVC get ];
//upload all the pending messages
UINavigationController *devNavController=[[MyappMgr get]getDeveloperNavigationController ];

[devNavController pushViewController:inboxVC animated:YES];
[devNavController setNavigationBarHidden:NO];

我得到了异常

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported (<MyInboxVC: 0x1452a0>)'

这是什么意思?我做错了什么?

【问题讨论】:

    标签: iphone ios uiviewcontroller


    【解决方案1】:

    我相信当您快速执行某些操作时,也会发生这种情况。我像这样构建一些东西:

    if(![self.navigationController.topViewController isKindOfClass:[YOURCLASS class]]) {
    

    【讨论】:

    • 我在一个非常简单的应用程序中遇到了同样的问题。这为我解决了。
    • 我有这个检查,但异常仍然存在。当第二次推送发生时,topViewController 还没有改变。如果我在没有动画的情况下推动,它会起作用。有人可以帮忙吗?
    【解决方案2】:

    首先处理崩溃,以免它杀死你的应用程序:

    @try {
        [self.navController pushViewController:viewController animated:NO];
    } @catch (NSException * e) {
        NSLog(@"Exception: %@", e);
    } @finally {
        //NSLog(@"finally");
    }
    

    如果出现错误,请使用 popTo

    - (void)pushViewController:(UIViewController *)viewController {
      if (viewController) {
        @try {
            [self.navController pushViewController:viewController animated:NO];
        } @catch (NSException * ex) {
            //“Pushing the same view controller instance more than once is not supported” 
            //NSInvalidArgumentException
            NSLog(@"Exception: [%@]:%@",[ex  class], ex );
            NSLog(@"ex.name:'%@'", ex.name);
            NSLog(@"ex.reason:'%@'", ex.reason);
            //Full error includes class pointer address so only care if it starts with this error
            NSRange range = [ex.reason rangeOfString:@"Pushing the same view controller instance more than once is not supported"];
    
            if ([ex.name isEqualToString:@"NSInvalidArgumentException"] &&
               range.location != NSNotFound) {
                //view controller already exists in the stack - just pop back to it
                [self.navController popToViewController:viewController animated:NO];
            } else {
                NSLog(@"ERROR:UNHANDLED EXCEPTION TYPE:%@", ex);
            }
        } @finally {
            //NSLog(@"finally");
        }
      } else {
        NSLog(@"ERROR:pushViewController: viewController is nil");
      }
    }
    

    【讨论】:

    • 这是“修复”症状,而不是根本原因。
    • 我遇到了同样的问题,尝试添加 try, catch 块,但它永远不会进入 catch 块。我错过了什么吗??
    【解决方案3】:

    表示[MyInboxVC get]返回的ViewController已经在devNavController的导航栈中。您不能多次将同一个对象添加到堆栈中。

    显然,您之前已经推送了MyInboxVC。确保在不再需要时将其弹出。

    这是“这是什么意思”的答案,但没有足够的信息知道您需要做什么来解决它。

    我的猜测是您的导航堆栈比您预期的要大,这意味着您没有像应有的那样频繁弹出。

    【讨论】:

      【解决方案4】:

      您是否将其作为 segue 的一部分执行?如果是,则无需将 VC 推送到导航控制器上,因为 segue 已经完成了。这就是您发生错误的原因 - 您正在推送一个已经在 NavController 堆栈上的 VC。

      【讨论】:

        【解决方案5】:

        这意味着当它已经在其中时,您正在将相同的视图控制器对象再次推送到堆栈。

        [self.navigationController pushViewController:viewControllerObj animated:NO];
        
        [self.navigationController pushViewController:viewControllerObj animated:NO];
        

        检查你是否在循环中推入,或者你是否不小心多次放置代码..

        【讨论】:

        • 在循环内。
        【解决方案6】:

        这个问题的主要原因,很明显,如果推送视图控制器的代码被多次调用。发生这种情况的原因有很多,最常见的错误是从后台线程触发回调方法时,该方法可能在仍在推送视图控制器时执行多次。 例子: 点击按钮时在后台线程上调用服务 api,这将允许您多次按下按钮,因此推动视图控制器的回调被多次调用。 只要您不想通过不多次推送来解决原始问题,@Melvin 和@Sam 解决方案就有效。

        【讨论】:

          【解决方案7】:

          这是 UINavigationController 的预期行为,当尝试推送堆栈中已经存在的视图控制器时会引发异常(它来自 iOS 2.2)。

          【讨论】:

            【解决方案8】:

            这发生在我的栏按钮点击发生得太快,并且很难重现,除非你在按钮点击时发疯了。以下通过禁用按钮,启动导航推送,然后在主线程上启用按钮来修复它(因为它会在推送发生动画后调用)。

            - (void)showMore
            {
                self.navigationItem.leftBarButtonItem.enabled = NO;
                [self.navigationController pushViewController:moreVC animated:YES];
                [self.navigationItem.leftBarButtonItem performSelectorOnMainThread:@selector(setEnabled:) withObject:@(YES) waitUntilDone:NO];
            }
            

            【讨论】:

              【解决方案9】:

              确保您没有在导航堆栈中添加两次视图控制器。 例如 - 在下面的示例中 self.mainViewC 被推送两次,因为它最初是在 navController 中实例化的,然后在最后一行再次被推送到 navController,这将导致此问题。

                navController=[[UINavigationController alloc] initWithRootViewController:self.mainViewC];  
                self.window.rootViewController = navController;
                [self.window makeKeyAndVisible];        
                [navController pushViewController:self.mainViewC animated:NO]; 
              

              在这种情况下,mainViewC 在编写 initWithRootViewController 时已经被添加到堆栈中。不再需要 pushViewController。

              【讨论】:

                【解决方案10】:

                我遇到的另一个选项是 [MyInboxVC get ] 根本没有返回 MyInboxVC 对象的实例。一个明显的迹象是错误是说“不支持多次推送同一个视图控制器实例(notTheInboxVC:0x9e31660)”,即。多次推送的类不是 MyInboxVC 预期的(未分配 MyInboxVC 的失败)

                【讨论】:

                  【解决方案11】:

                  我使用 IB segue 修复了相同的问题(Swift 4):

                  override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
                      return navigationController?.topViewController is MainController ? true : false 
                  }
                  

                  【讨论】:

                    【解决方案12】:

                    在我的情况下,我正在推送一个视图控制器,但随后还尝试清除导航堆栈,以便在这个新的 VC 显示后没有 vc 可以弹出

                    self.show(viewController, sender: nil)
                    
                    if clearNavigationStack {
                        self.navigationController?.viewControllers = [viewcontroller]
                    }
                    

                    您不能在推送视图控制器后直接执行此操作,您需要等到视图控制器完全显示后才能尝试重置导航堆栈

                    【讨论】:

                      【解决方案13】:

                      [devNavController pushViewController:inboxVC 动画:NO]; 设置动画为 NO

                      【讨论】:

                        猜你喜欢
                        • 2011-01-03
                        • 2016-05-26
                        • 1970-01-01
                        • 2011-11-14
                        • 2020-08-30
                        • 2021-06-03
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-09-07
                        相关资源
                        最近更新 更多