50 votes

Exception "Pousser la même instance de contrôleur de vue plus d'une fois n'est pas supporté".

J'utilise le code suivant pour récupérer des messages et les placer dans ma boîte de réception.

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

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

Je reçois l'exception

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

Qu'est-ce que cela signifie ? Qu'est-ce que je fais de mal ?

2voto

Elie Points 1

La raison principale de ce problème, évidemment si le code qui a poussé le contrôleur de vue est appelé plus d'une fois. Cela peut se produire pour de nombreuses raisons, l'erreur la plus courante étant qu'une méthode de rappel est déclenchée à partir d'un thread d'arrière-plan, où cette méthode peut être exécutée plus d'une fois alors qu'elle continue à pousser le contrôleur de vue. Exemple : L'appel d'un service api sur un thread d'arrière-plan lorsque vous appuyez sur un bouton, ce qui vous permet d'appuyer sur le bouton plus d'une fois, et donc le callback qui pousse le contrôleur de vue est appelé plus d'une fois. La solution de @Melvin et @Sam est valable tant que vous ne voulez pas résoudre le problème original en ne poussant pas plus d'une fois.

1voto

Sivaprasad Points 56

Il s'agit d'un comportement attendu de UINavigationController où une exception est levée lorsqu'on essaie de pousser un contrôleur de vue qui est déjà présent dans la pile (il existe depuis iOS 2.2).

1voto

pulse4life Points 733

Cela m'arrivait lorsque le clic sur le bouton de la barre était trop rapide, et c'était difficile à reproduire, à moins que vous ne vous lanciez à fond dans l'utilisation des boutons. La méthode suivante a permis de résoudre le problème en désactivant le bouton, en démarrant le push de la navigation, puis en activant le bouton sur le thread principal (parce qu'il serait appelé après que l'animation du push se soit produite).

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

1voto

Kavish Points 36

Assurez-vous que vous n'ajoutez pas le contrôleur de vue deux fois dans la pile de navigation. Par exemple, dans l'exemple ci-dessous, self.mainViewC est poussé deux fois parce qu'il est initialement instancié dans le navController, et est ensuite poussé à nouveau sur le navController dans la dernière ligne, ce qui causerait ce problème.

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

Dans ce cas, mainViewC a déjà été ajouté à la pile lorsque initWithRootViewController a été écrit. Il n'y a pas besoin de pousserViewController à nouveau.

1voto

Fonix Points 2289

Dans mon cas, je poussais un contrôleur de vue, mais j'essayais aussi de vider la pile de navigation pour qu'il n'y ait pas de VC vers lesquels se diriger après l'affichage de ce nouveau VC.

self.show(viewController, sender: nil)

if clearNavigationStack {
    self.navigationController?.viewControllers = [viewcontroller]
}

vous ne pouvez pas le faire directement après avoir poussé un contrôleur de vue, vous devrez attendre que le contrôleur de vue soit complètement affiché avant d'essayer de réinitialiser la pile de navigation

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X