dismissModalViewControllerAnimated: (e dismissViewControllerAnimated) schiantarsi in iOS 5
-
27-10-2019 - |
Domanda
Non riesco a trovare alcuna spiegazione logica, ma resta il fatto che, in iOS 5 (xCode 4.2), se io presentModalView: * animato: Sì, posso chiamare dismissModalViewAnimated: * bene, ma se mi chiamare presentModalView: * animato: NO, quindi chiamando il metodo crash respingere. (Questo funziona lo stesso se uso il nuovo presentViewController: animato: il completamento: + dismissViewControllerAnimated :). Sto andando provare a lavorare intorno a questo per ora (non voglio che la presentazione animata) e segnalare un bug ad Apple, ma mi è stato battendo la testa su questo per un po '. Qualsiasi e tutti i suggerimenti sono i benvenuti. Non molto là fuori su iOS 5, quindi per favore aiuto se potete. codice di esempio che non va in crash in iOS 4 o iOS 5:
LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
[self presentModalViewController:loginController animated:YES];
[loginController release];
...
[self dismissModalViewControllerAnimated:YES];
Questa andrà in crash in iOS 5 con EXC_BAD_ACCESS sulla chiamata respingere:
LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
[self presentModalViewController:loginController animated:NO];
[loginController release];
...
[self dismissModalViewControllerAnimated:YES]; //crashes with EXC_BAD _ACCESS
Una nota: Ho un'animazione all'interno della loginController quello che succede sul viewDidLoad. Andando a vedere se prendere che fuori cambia nulla, ma volevo ottenere questo là fuori da quando ho bisogno di una soluzione al più presto.
[Modifica] flusso di codice completa ... In AppDelegate, applicazione: didFinishLaunchingWithOptions:
if (!loggedIn) [myViewController showLoginPanel];
In myViewController:
- (void)showLoginPanel {
LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
[self presentViewController:loginController animated:NO completion:nil];
} else {
[self presentModalViewController:loginController animated:NO]; //iOS 4 works fine with or without animation
}
[loginController release];
}
In loginController:
- (IBAction)closeLoginWindow {
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloseLoginWindow" object:nil];
} //doing it this way because calling on the self.parentViewController doesn't work
Torna in myViewController:
- (void) viewDidLoad
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeLoginWindow) name:@"CloseLoginWindow" object:nil];
...
- (void)closeLoginWindow {
if ([self respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) {
[self dismissViewControllerAnimated:YES completion:nil]; //iOS 5 crashes only if presentation was not animated
} else [self dismissModalViewControllerAnimated:YES]; //deleting the previous condition, iOS 5 still crashes if presentation was not animated
}
Soluzione
In iOS5 la gestione del ai cicli di vita in qualche modo cambiato e non posso spiegare che problema in dettaglio. In ogni caso, la correzione è di rinviare tale flusso di lavoro da applicationDidFinishLaunchingWithOptions a applicationDidBecomeActive. Sembra che qualcosa non è inizializzato proprio al richiamo del applicationDidFinishLaunchingWithOptions.
- (void)applicationDidFinishLaunchingWithOptions:... {
// in order to do this only at launching, but not on every activation
// Declaration as property for example
applicationDidLaunch = YES;
}
- (void) applicationDidBecomeActive:(UIApplication *)application {
if (applicationDidLaunch) {
applicationDidLaunch = NO;
[Start your login Workflow with modal view presenting here]
}
}
Curioso di ur commenti:) ....
Altri suggerimenti
I aggiungerà i miei 2 centesimi: ho avuto ImagePickerController e preso il suo lavoro di congedo solo quando non ha rilasciato il selettore manuale (IOS 5 SDK)
.. per il vostro caso ho potuto offrire tale soluzione: Linea 1. Rimuovere - [rilascio loginController]; 2. Per evitare perdite di memoria aggiungono loginController come una proprietà per il controller attuale e rilasciarlo solo in dealloc () del regolatore di corrente:
@interface myViewController : UIViewController
@property (nonatomic, retain) LoginController *loginController;
@end
...
@implementation myViewController
- (void)showLoginPanel {
self.loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
// ... something goes here
}
-(IBAction)loginClose()
{
// this should close all windows as far as you call it from current (main) controller
[self dismissModalViewControllerAnimated:YES];
// ... then anything you want EXCEPT [loginController release];
}
-(void)dealloc()
{
[loginController release];
}
@end
Buona fortuna:)
P.S. Ho appena scritto questo modo è solo un idea di come barare esso. Somebosy può correggere me ... anche se comunque ha funzionato per me.