Intentando descartar UIAlertController con un presentador desconocido

Mi aplicación se bloqueó, y debe ser debido a UIAlertController.

Este problema se produce solo en iOS 8.x, donde UIAlertController está disponible. El hecho extraño es que mi aplicación no utiliza UIAlertViewController ni UIAlertView .

Los informes me dicen:

Trying to dismiss UIAlertController <UIAlertController: 0x172c5d80> with unknown presenter. 

¿Cómo puede suceder esto?

Yo pense acerca de

  1. Deshacer Sistema AlertView mostrado gracias al gesto de sacudida
  2. WebView desasignado mientras un post o un cuadro de dialog genérico todavía está en la pantalla
  3. Alerta de batería baja

pero ninguno de estos casos me lleva al crash.

Lo que me sugiere el logging de lockings es el hecho de que el SO muestra un AlertView que se adjuntará a la window de mi aplicación y, en algunas circunstancias, perderá el controller de vista principal que presentó el UIAlertViewController.

¿Alguna idea de cómo encontrar el problema?

Aquí el rastro de la stack

 _________________________________ 0 CoreFoundation 0x2bc0c45f __exceptionPreprocess + 127 1 libobjc.A.dylib 0x39c79c8b objc_exception_throw + 36 2 CoreFoundation 0x2bc0c3a5 +[NSException raise:format:] + 110 3 UIKit 0x2f4ad13d -[UIAlertController _dismissAnimated:triggeringAction:triggenetworkingByPopoverDimmingView:] + 414 4 UIKit 0x2f4acf97 -[UIAlertController _dismissAnimated:triggeringAction:] + 28 5 UIKit 0x2f590a0b -[_UIAlertControllerActionView touchesEnded:withEvent:] + 160 6 UIKit 0x2f159567 -[UIWindow _sendTouchesForEvent:] + 520 7 UIKit 0x2f152e31 -[UIWindow sendEvent:] + 542 8 UIKit 0x2f129759 -[UIApplication sendEvent:] + 194 9 UIKit 0x2f39d2f9 _UIApplicationHandleEventFromQueueEvent + 14166 10 UIKit 0x2f1281a9 _UIApplicationHandleEventQueue + 1350 11 CoreFoundation 0x2bbd2fbf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12 12 CoreFoundation 0x2bbd23cf __CFRunLoopDoSources0 + 216 13 CoreFoundation 0x2bbd0a35 __CFRunLoopRun + 770 14 CoreFoundation 0x2bb1e3b1 CFRunLoopRunSpecific + 474 15 CoreFoundation 0x2bb1e1c3 CFRunLoopRunInMode + 104 16 GraphicsServices 0x3308d201 GSEventRunModal + 134 17 UIKit 0x2f18843d UIApplicationMain + 1438 18 MyApp 0x00028a07 main (main.mm:16) 

EDITAR

Agujeros preguntaron acerca de la initialization de mi window. Aquí el código de mi AppDelegate

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[MyAppCustomWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; _mainViewController = [[MyAppContainerViewController alloc] initWithNibName:nil bundle:nil]; _mainStatusBarVC = [[MyAppStatusBarVC alloc] initWithRootVC:_mainViewController]; [self.window setRootViewController:_mainStatusBarVC]; [self.window makeKeyAndVisible]; return YES; } 

Apuesto a que su crash se produjo en el iPad.

En iPad, desde iOS8, UIActionSheet parece manejarse con un UIAlertController

Con este código,

 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if(buttonIndex == 1) return; // Cancel button [self doSomeViewControllerDismisses]; } 

Mi aplicación se bloqueó con el mismo error que recibió.
Para evitar esto, simplemente envío la llamada de rechazo compleja en la próxima ejecución de MainThread, para darle al UIAlertViewController oculto la oportunidad de lanzar correctamente.

 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if(buttonIndex == 1) return; // Cancel button dispatch_async(dispatch_get_main_queue(), ^{ [self doSomeViewControllerDismisses]; }); } 

Una traza de stack de esta forma generalmente indica que ha navegado lejos de un UIViewController mientras que una alerta de que la tenía presente todavía está descartando.

El remedio general para eso es presentar o descartar controlleres en UIAlertViewDelegate's alertView: didDismissWithButtonIndex: método, desde entonces está seguro de que el presentador no desaparecerá durante ningún despido.

En su caso, si no puede encontrar ningún caso reproducible, puede intentar comprobar presentedViewController antes de presentar / descartar un controller y ver si eso da resultado.

Pero probablemente, si audita las transiciones de su controller, encontrará en alguna parte que responder a una alerta del sistema podría desencadenar una navigation mediante progtwigción. ¿Tiene alguna funcionalidad que genere una alerta del sistema para la autorización del usuario, como el acceso a las fotos o lo que sea, y al negarlo resultaría en que un controller sea despedido programáticamente por su event handling errores? Eso parece un escenario razonablemente plausible.

intente descartar en hilo principal Alertview usando Block en main thrad.

 dispatch_async(dispatch_get_main_queue(), { () -> Void in // Write your alert view code in swift language . })