“不止一次推送相同的视图控制器实例”不受支持“exception

我正在使用下面的代码来检索一些消息,并将其放入我的收件箱。

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>)' 

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

我相信,当你做了一些非常快的行动,这也可能发生。 我build立这样的东西:

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

编辑//

这种情况在具有慢速animation的旧设备上发生的频率更高,如iphone 3或3gs

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

 @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"); } } 

这意味着从[MyInboxVC get]返回的ViewController已经在devNavController的导航栈中。 您不能将相同的对象多次添加到堆栈。

显然,你已经有一个MyInboxVC推送。 确保在不再需要时将其popup。

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

我的猜测是你的导航堆栈正在增长得比你期望的大,这意味着你不会像你应该那样频繁地popup。

你是否将这作为赛格的一部分? 如果是的话,就不需要将VC推到你的导航控制器上,因为这样的话就可以完成了。 这就是为什么你的错误正在发生 – 你正在推动一个已经在NavController堆栈上的VC。

这意味着你正在推动同一个viewcontroller对象,当它已经在那里时再次堆叠。

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

检查你是否在一个循环内推动,或者如果你不小心将代码放置一次以上..

这是UINavigationController的一个预期的行为,当试图推送一个已经存在于堆栈中的视图控制器(它来自iOS 2.2)时抛出exception。

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

我经历的另一个select是[MyInboxVC get]根本没有返回一个MyInboxVC对象的实例。 告诉故事的迹象是,错误是说'不止一次推送相同的视图控制器实例不支持(notTheBoxVC:0x9e31660)“即。 被多次推送的类不是预期的MyInboxVC(MyInboxVC没有被分配)

这发生在一个酒吧button点击发生太快,很难再现,除非你坚持button水龙头。 下面通过禁用button,启动导航推送,然后启用主线程上的button(因为它将在发生推送的animation之后调用)来修复它。

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

确保在导航堆栈中不添加视图控制器两次。 例如 –

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

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

[devNavController pushViewController:inboxVC animated:NO]; 设置animation为NO