2011-08-16 8 views
35

Estoy usando el siguiente código para recuperar algunos mensajes y ponerlos en mi bandeja de entrada."Impulsar la misma instancia de controlador de vista más de una vez no es compatible" excepción

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

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

tengo la excepción

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

¿Qué significa? ¿Qué estoy haciendo mal?

Respuesta

62

Creo que cuando haces algunas acciones realmente rápido, esto también puede suceder. Construyo algo en este aspecto:

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

editar //

esto ocurre más a menudo en los dispositivos antiguos con animaciones lentas, como el iPhone 3 o 3GS

+0

he experimentado el mismo problema en una aplicación muy simple. Esto lo resolvió para mí. – neoneye

+4

Tengo este control pero la excepción todavía existe. Cuando ocurre el segundo empujón, el controlView superior no ha cambiado aún. Si presiono sin animación, funciona. ¿Alguien puede ayudarme en esto? – edwardtoday

5

Significa que el ViewController devuelto desde [MyInboxVC get] ya está en la pila de navegación de devNavController. No puede agregar el mismo objeto a la pila varias veces.

Aparentemente, ya tiene un MyInboxVC empujado anteriormente. Asegúrate de haberlo abierto cuando ya no era necesario.

Esa es la respuesta "¿qué significa eso?", Pero no tiene suficiente información para saber lo que debe hacer para solucionarlo.

Supongo que su pila de navegación está creciendo más de lo que esperaba, lo que significa que no está apareciendo tantas veces como debería.

1

Este es un comportamiento esperado de UINavigationController donde se lanza una excepción cuando se trata de empujar un controlador de vista que ya está presente en la pila (Está ahí desde iOS 2.2).

17

manejar primer lugar del accidente por lo que doesnt matar su aplicación:

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

Entonces, si usted consigue utilizar el error 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"); 
    } 
} 
+19

Esto está "arreglando" el síntoma y no la causa subyacente. –

+0

Estoy teniendo el mismo problema, intenté agregar try, catch block pero nunca entra en catch block. ¿¿Me estoy perdiendo de algo?? –

3

Significa que está presionando el mismo objeto viewcontroller para apilar nuevamente cuando ya está allí.

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

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

verificación si ur empujando dentro de un bucle o si accidentalmente U'VE colocado el código más de una vez ..

+1

dentro del lazo. –

0

Otra opción que he experimentado es que [MyInboxVC llegar] no devuelve una instancia de un objeto MyInboxVC en absoluto. Un signo revelador de esto sería que el error es "Empujar la misma instancia de controlador de vista más de una vez no es compatible (no TheInboxVC: 0x9e31660)", es decir. la clase que se envía más de una vez no se espera MyInboxVC (no se asigna una caída de MyInboxVC)

1

Motivo principal de este problema, obviamente si el código que envió el controlador de vista se llama más de una vez. Esto podría ocurrir por muchas razones, el error más común cuando se desencadena un método de devolución de llamada desde una cadena de fondo, donde este método podría ejecutarse más de una vez mientras todavía está presionando el controlador de vista. Ejemplo: Llamar a una aplicación de servicio en el hilo de fondo al tocar un botón, lo que le permitirá presionar el botón más de una vez, y por lo tanto la devolución de llamada que empuja al controlador de vista se llama más de una vez. La solución @Melvin y @Sam es válida siempre que no desee solucionar el problema original al no presionar más de una vez.

3

¿Lo está haciendo como parte de una segue? Si es así, no es necesario insertar un VC en el Controlador de navegación porque el cambio ya lo hará. Es por eso que su error está ocurriendo, está presionando un VC que ya está en la pila del NavController.

+0

Esta es la respuesta correcta muchas gracias hombre: D –

-1

[devNavController pushViewController: inboxVC animated: NO]; Conjunto animado como NO

0

Esto me estaba sucediendo en un clic de botón de barra sucediendo demasiado rápido, y era difícil de reproducir, a menos que se volviera loco con los botones. Lo siguiente lo solucionó desactivando el botón, iniciando el impulso de navegación, luego habilitando el botón en el hilo principal (porque se llamaría después de la animación del impulso).

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

Asegúrese de no agregar el controlador de vista dos veces en la pila de navegación. EG -

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

En este caso mainViewC ya se ha agregado a la pila cuando se escribió initWithRootViewController. No hay necesidad de pushViewController nuevamente.

0

i fijo el mismo problema (Swift 4) con IB segue usando:

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