Pregunta

Estoy tratando de mostrar una vista modal justo después de que otra vista se haya presentado de manera modal (la segunda es una vista de carga que aparece).

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    LoadViewController *loader = [[LoadViewController alloc] init];
    [self presentModalViewController: loader animated:NO];
    [loader release];
}

Pero cuando hago esto, obtengo una " Señal recibida del programa: " EXC_BAD_ACCESS ". " error.

El seguimiento de la pila es:

0  0x30b43234 in -[UIWindowController transitionViewDidComplete:fromView:toView:]
1  0x3095828e in -[UITransitionView notifyDidCompleteTransition:]
2  0x3091af0d in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
3  0x3091ad7c in -[UIViewAnimationState animationDidStop:finished:]
4  0x0051e331 in run_animation_callbacks
5  0x0051e109 in CA::timer_callback
6  0x302454a0 in CFRunLoopRunSpecific
7  0x30244628 in CFRunLoopRunInMode
8  0x32044c31 in GSEventRunModal
9  0x32044cf6 in GSEventRun
10 0x309021ee in UIApplicationMain
11 0x00002154 in main at main.m:14

¿Alguna idea? Estoy totalmente perplejo! La vista de carga está vacía, por lo que definitivamente no hay nada dentro que esté causando el error. ¿Es algo que ver con lanzar 2 vistas de manera modal en el mismo bucle de eventos o algo así?

Gracias,

Mike

Edit: Muy extraño ... Lo he modificado ligeramente para que la vista de carga se muestre después de un pequeño retraso, ¡y esto funciona bien! ¡Así que parece ser algo dentro del mismo bucle de eventos!

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    [self performSelector:@selector(doit) withObject:nil afterDelay:0.1];
}

- (void)doit {
    [self presentModalViewController:loader animated:YES];  
}
¿Fue útil?

Solución

Lo modifiqué ligeramente para que la vista de carga se muestre después de un pequeño retraso, ¡y esto funciona bien! ¡Así que parece ser algo dentro del mismo bucle de eventos!

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    [self performSelector:@selector(doit) withObject:nil afterDelay:0.1];
}

- (void)doit {
    [self presentModalViewController:loader animated:YES];  
}

Otros consejos

Creo que reproduje el mismo error en iOS 4. En mi aplicación, el bloqueo se produjo de manera constante al intentar mostrar una segunda vista modal inmediatamente después de mostrar una primera vista modal. Luché por unas pocas horas volviéndome loca.

Después de leer las publicaciones en este hilo, traté de crear un ejemplo simple reproducible usando la plantilla de la aplicación de la Barra de pestañas. Pude usar el UIImagePickerController para mostrar la primera vista modal después de responder a un botón, haga clic en "FirstViewController.m". Cuando intenté mostrar el UIImagePickerController nuevamente (después de manejar el mensaje imagePickerControllerDidCancel), la aplicación se bloqueó con el mismo error.

En el dispositivo, simplemente no había ni idea de lo que estaba pasando. Sin embargo, cuando ejecuté el código en el simulador, tuve la suerte de obtener este mensaje en la consola:

*** Finalización de la aplicación debido a la excepción no detectada 'NSInternalInconsistencyException', razón: 'Intentando iniciar una transición modal de a mientras una transición ya está en curso. Espere a ver viewDidAppear / viewDidDisappear para saber que la transición actual se ha completado '

Parece que mi única opción es seguir el consejo del mensaje de error y simplemente esperar a que aparezca viewDidAppear (usando una marca para indicar que estoy en este modo especial) y luego cargar la segunda vista modal.

Aquí está la traza completa de la pila para completarla:

** Call stack at first throw:
(
 0   CoreFoundation                      0x0238c919 __exceptionPreprocess + 185
 1   libobjc.A.dylib                     0x024da5de objc_exception_throw + 47
 2   CoreFoundation                      0x02345078 +[NSException raise:format:arguments:] + 136
 3   Foundation                          0x000ab8cf -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
 4   UIKit                               0x00544317 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 212
 5   UIKit                               0x0035c769 -[UIViewController presentModalViewController:withTransition:] + 2937
 6   TestTempDelete                      0x000021cf -[FirstViewController showImagePicker] + 167
 7   Foundation                          0x0002fcea __NSFireDelayedPerform + 441
 8   CoreFoundation                      0x0236dd43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
 9   CoreFoundation                      0x0236f384 __CFRunLoopDoTimer + 1364
 10  CoreFoundation                      0x022cbd09 __CFRunLoopRun + 1817
 11  CoreFoundation                      0x022cb280 CFRunLoopRunSpecific + 208
 12  CoreFoundation                      0x022cb1a1 CFRunLoopRunInMode + 97
 13  GraphicsServices                    0x02bf12c8 GSEventRunModal + 217
 14  GraphicsServices                    0x02bf138d GSEventRun + 115
 15  UIKit                               0x002beb58 UIApplicationMain + 1160
 16  TestTempDelete                      0x00001eb4 main + 102
 17  TestTempDelete                      0x00001e45 start + 53

Espero que esto ayude.

** Como se dijo anteriormente, use isIgnoringInteractionEvents

//Check if the app is ignoring interatctions, if so, add a delay for 1 sec
if([[UIApplication sharedApplication] isIgnoringInteractionEvents]==TRUE) {
        [currentViewController performSelector:@selector(presentModalViewController:animated:) withObject:screen afterDelay:1];
    } else {
        [currentViewController presentModalViewController:screen animated:YES];
    }

Es posible si obtiene esto después de hacer clic en un botón que estaba vinculado a su código en Interface Builder, que tiene dos acciones vinculadas a un botón (tal vez si tuviera una vista modal vinculada a un botón, entonces Duplicé el botón y enlazé otra vista modal). Esto intentará despedirlos y, por lo tanto, fallará con ese mensaje.

Encontré la misma excepción

  

Finalización de la aplicación debido a la excepción no detectada 'NSInternalInconsistencyException', razón: 'Intentando iniciar una transición modal de a mientras una transición ya está en curso. Espere a que viewDidAppear / viewDidDisappear sepa que la transición actual se ha completado '

Como se sugirió anteriormente, traté de retrasar la presentación de una transición modal, pero eso realmente no ayudó. ¡Entonces descubrí que tenía múltiples IBActions conectadas al evento TouchUpInside de mi botón! En mi caso, se iniciarían dos IBActions: presentar un selector de personas de manera modal y presentar un selector de imágenes de manera modal. Esto explica el mensaje de error. ¡Comprueba si tienes varias IBActions conectadas!

Su problema es más probable en el método que contiene y presenta el método en el que se encuentra viewDidAppear, o en el método init / viewDidLoad / viewWillAppear de LoadViewController.

Establezca algunos puntos de ruptura y siga hasta que se bloquee ...

Tuve un error similar al hacer clic en un UIButton para abrir un Modal View . Cambié el UIButton's listener de UIControlEventAllEvents a UIControlEventTouchUpInside . Básicamente, se activó la Vista modal en Touch Down Inside y luego nuevamente en Touch Up Inside .

Tuve el mismo problema debido a la falta de coincidencia entre los nombres en

HelpViewController *controller = [[HelpViewController alloc] initWithNibName:@"HelpView" bundle:nil];

y el nombre del archivo .xib real.

Creo que este problema tiene algo que ver con un problema que también encontré. Es muy fácil de reproducir:

Crear nuevo proyecto XCode " Aplicación de utilidad " ;. En el FlipsideViewController.m acaba de insertar el siguiente método:

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear: animated];
  [self showInfo];
}

Si hace esto, inicie la aplicación, entonces la vista de la otra cara se activará a la derecha lejos. Tan pronto como presione la tecla " Listo " Botón en la cara opuesta, volverá a la vista principal, que dispara viewDidAppear de nuevo y regresa directamente al lado opuesto- ver. Tan pronto como se muestra la cara de impresión, la aplicación se detiene, sin memoria Se llaman "deallocators": es como si hubiera presionado el botón de inicio.

Cuando estaba usando algunas propiedades adicionales en esas vistas, también obtuve la excepción, Así que reduje el código a la cantidad mínima ...

Realmente no tengo ni idea, lo que realmente es este problema ...

Saludos cordiales, Tobias

Realmente depende de lo que estén haciendo las rutinas de soporte para viewDidAppear . Por ejemplo, si presentModalViewController: animated: no conserva loader , el bloqueo puede deberse a UIWindowController que intenta hablar sobre loader que ya se ha publicado (al final de la rutina que publicaste).

Tuve un problema similar al usar la misma técnica que tú para implementar una vista de carga. Se bloquearía cuando la vista de carga se descartara al final de la carga. En mi caso, el problema provino del hecho de que tan pronto como se desestimó la vista de carga, se volvió a llamar a viewDidAppear e intentó presentar la vista de carga nuevamente, lo que presumiblemente provocó el bloqueo. Lo arreglé simplemente comprobando si la vista de carga se había presentado antes:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    if(needDisplayLoader)
        [self presentModalViewController: loader animated:NO];
}

Luego establezco needDisplayLoader en NO antes de descartar la vista del cargador

Espero que esto ayude ...

Me encontré con este problema ahora mismo, y lo corregí usando el selector: afterDelay la sugerencia anterior. Solo para agregar, compilé (sin la solución) bajo la versión beta del iPhone OS 4.0, ¡y NO CRASH! Por lo tanto, el error en XCode parece haberse solucionado en la siguiente generación. No es que esto nos sirva de nada a ninguno de nosotros hoy, pero, para que todos lo sepan, realmente fue un error en Xcode y no necesariamente algo que estuviéramos haciendo mal en nuestros estilos de codificación.

Tenía exactamente el mismo problema. Resuelto con lo sugerido anteriormente ...

[self performSelector: @selector (doit) withObject: nil afterDelay: 0.5];

Tuvo que usar un retraso de 0,5 segundos. Posiblemente porque estaba realizando presentModalViewController directamente después de un UIPickerViewController modal.

Acabo de tener este problema y resultó que mi problema se debía a que estaba descartado a mi delegado de protocolo.

Creo que el motivo del bucle es que el nuevo controlador de vista que está cargando tiene un método viewDidAppear de forma predeterminada y tiene

[super viewDidAppear animated];

lo que significa que volverá a llamar a viewDidAppear de su controlador de vista principal, así que irá en un bucle

en Viewcontroller que estás presentando tienes un método como este, sin super viewdidapper:

-(void)viewDidAppear:(BOOL)animated{
    //[super viewDidAppear:animated]; no super

}

EXC_BAD_ACCESS es un error de memoria. Probablemente esté intentando usar un objeto que ya ha sido liberado / desasignado. Esta respuesta proporciona algunos consejos para depurar estos problemas:

Depuración EXC_BAD_ACCESS

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top