Arresto anomalo dell'iPhone durante la presentazione del controller di visualizzazione modale
-
05-07-2019 - |
Domanda
Sto cercando di visualizzare una vista modale subito dopo che un'altra vista è stata presentata modalmente (la seconda è una vista di caricamento che appare).
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Show load
LoadViewController *loader = [[LoadViewController alloc] init];
[self presentModalViewController: loader animated:NO];
[loader release];
}
Ma quando lo faccio ricevo un segnale di programma ricevuto: " EXC_BAD_ACCESS ". " di errore.
La traccia dello stack è:
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
Qualche idea? Sono totalmente perplesso! La vista di caricamento è vuota, quindi non c'è assolutamente nulla che sta causando l'errore. Ha a che fare con l'avvio di 2 visualizzazioni in modo modale nello stesso loop di eventi o qualcosa del genere?
Grazie,
Mike
Modifica: molto strano ... L'ho modificato leggermente in modo che la vista di caricamento sia mostrata dopo un piccolo ritardo, e questo funziona bene! Quindi sembra essere qualcosa all'interno dello stesso ciclo di eventi!
- (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];
}
Soluzione
L'ho modificato leggermente in modo che la visualizzazione di caricamento venga mostrata dopo un piccolo ritardo, e questo funziona benissimo! Quindi sembra essere qualcosa all'interno dello stesso ciclo di eventi!
- (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];
}
Altri suggerimenti
Credo di aver riprodotto lo stesso errore in iOS 4. Nella mia applicazione, l'arresto anomalo si è verificato in modo coerente quando si è tentato di mostrare una seconda vista modale immediatamente dopo aver mostrato una prima vista modale. Ho lottato per qualche ora impazzendo.
Dopo aver letto i post in questa discussione, ho provato a creare un semplice esempio riproducibile usando il modello Applicazione barra delle schede. Sono stato in grado di utilizzare UIImagePickerController per mostrare la prima vista modale dopo aver risposto a un clic del pulsante in "FirstViewController.m". Quando ho provato a mostrare di nuovo UIImagePickerController (dopo aver gestito il messaggio imagePickerControllerDidCancel), l'applicazione si è bloccata con lo stesso errore.
Sul dispositivo, semplicemente non c'era idea di cosa stesse succedendo. Tuttavia, quando ho eseguito il codice sul simulatore, ho avuto la fortuna di ricevere questo messaggio sulla console:
*** Terminare l'app a causa dell'eccezione non rilevata 'NSInternalInconsistencyException', motivo: 'Tentativo di iniziare una transizione modale da a mentre è già in corso una transizione. Attendi viewDidAppear / viewDidDisappear per sapere se la transizione corrente è stata completata "
Quindi sembra che la mia unica scelta sia quella di seguire il consiglio del messaggio di errore e semplicemente aspettare fino a viewDidAppear (usando un flag per indicare che sono in questa modalità speciale) e quindi caricare la seconda vista modale.
Ecco la traccia dello stack completo per completezza:
** 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
Spero che questo aiuti.
** Come detto in precedenza, utilizzare 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];
}
È possibile se ottieni questo dopo aver fatto clic su un pulsante collegato al tuo codice in Interface Builder, che hai due azioni collegate a un pulsante (forse se avessi una vista modale collegata a un pulsante, quindi duplicato il pulsante e collegato un'altra vista modale). Questo tenterà di licenziarli entrambi e quindi fallirà con quel messaggio.
Ho riscontrato la stessa eccezione
Termine dell'app a causa dell'eccezione non rilevata "NSInternalInconsistencyException", motivo: "Tentativo di iniziare una transizione modale da a mentre è già in corso una transizione. Attendi viewDidAppear / viewDidDisappear per sapere se la transizione corrente è stata completata '
Come suggerito in precedenza, ho cercato di ritardare la presentazione di una transizione modale, ma non mi è stato di grande aiuto. Ho quindi scoperto di avere più IBAzioni collegate all'evento TouchUpInside del mio pulsante !!! . Nel mio caso inizierebbero due IBActions: presentare un selettore di persone in modo modale e presentare un selettore di immagini in modo modale. Questo spiega il messaggio di errore. Controlla se hai più IBActions collegati!
Il tuo problema è molto probabilmente nel metodo che introduce e presenta il metodo in cui si trova viewDidAppear o nel metodo init / viewDidLoad / viewWillAppear di LoadViewController.
Imposta alcuni punti di interruzione e segui fino allo schianto ...
Ho avuto un errore simile quando ho cliccato su un UIButton
per aprire un Modal View
. Ho modificato il listener di UIButton
da UIControlEventAllEvents
a UIControlEventTouchUpInside
. Fondamentalmente, stava attivando la vista modale su Touch Down Inside
e poi di nuovo su Touch Up Inside
.
Ho avuto lo stesso problema a causa della mancata corrispondenza tra i nomi in
HelpViewController *controller = [[HelpViewController alloc] initWithNibName:@"HelpView" bundle:nil];
e il nome del file .xib effettivo.
Penso che questo problema abbia qualcosa a che fare con un problema che ho riscontrato anche. È molto facile da riprodurre:
Crea nuovo progetto XCode " Utility Utility " ;. In FlipsideViewController.m devi solo inserire il seguente metodo:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear: animated];
[self showInfo];
}
In questo caso, avvia l'applicazione, quindi la vista a rovescio verrà attivata a destra lontano. Non appena si preme il tasto " Fatto " Pulsante sulla vista a rovescio, tornerai indietro alla vista principale che spara viewDidAppear di nuovo e ritorna di nuovo al rovescio- vista. Non appena viene visualizzata la vista a rovescio, l'applicazione si interrompe, senza memoria si chiamano deallocatori - è proprio come hai premuto il tasto home.
Quando stavo usando alcune proprietà aggiuntive in quelle viste, ho anche ottenuto l'eccezione, così ho ridotto il codice al minimo ...
Non ho davvero idea di cosa sia davvero questo problema ...
Cordiali saluti, Tobias
Dipende davvero da cosa stanno facendo le routine di supporto per viewDidAppear
. Ad esempio, se presentModalViewController: animato:
non mantiene caricatore
, l'arresto potrebbe essere dovuto al UIWindowController
che sta cercando di parlare di loader
che è stato successivamente rilasciato (alla fine della routine che hai pubblicato).
Ho riscontrato un problema simile durante l'utilizzo della stessa tecnica utilizzata per implementare una vista di caricamento. Si arresterebbe in modo anomalo quando la visualizzazione di caricamento veniva chiusa alla fine del caricamento. Nel mio caso, il problema derivava dal fatto che non appena la vista di caricamento veniva chiusa viewDidAppear veniva richiamato e tentava di presentare nuovamente la vista di caricamento, che presumibilmente ha provocato l'arresto anomalo. Ho risolto semplicemente controllando se la vista di caricamento era stata presentata prima:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if(needDisplayLoader)
[self presentModalViewController: loader animated:NO];
}
Quindi ho impostato needDisplayLoader su NO prima di chiudere la vista Caricatore
Spero che questo aiuti ...
Ho riscontrato questo problema in questo momento e l'ho corretto utilizzando il selettore: suggerimento AfterDelay sopra. Solo per aggiungere, ho compilato (senza la correzione) sotto iPhone OS 4.0 beta e NO CRASH! Quindi, il bug in XCode sembra essere stato corretto nella prossima generazione. Non che questo sia utile a nessuno di noi oggi, ma, per questo lo sapete tutti, era veramente un bug in Xcode e non necessariamente qualcosa che stessimo facendo di sbagliato nei nostri stili di codifica.
Aveva lo stesso identico problema. Risolto con il suggerito sopra ...
[self performSelector: @selector (doit) withObject: zero afterDelay: 0.5];
Ho dovuto usare un ritardo di 0,5 secondi. Forse perché stavo eseguendo presentModalViewController direttamente dopo un UIPickerViewController modale.
Ho appena avuto questo problema e si è scoperto che il mio problema era dovuto al fatto che ero stato deallocato il mio delegato di protocollo.
Penso che il motivo del loop sia che il nuovo view controller che stai caricando ha un metodo viewDidAppear per impostazione predefinita e che ha
[super viewDidAppear animated];
il che significa che richiamerà nuovamente il viewDidApp del controller della vista principale, in questo modo andrà in loop
in Viewcontroller che stai presentando ha un metodo come questo, senza super viewdidapper:
-(void)viewDidAppear:(BOOL)animated{
//[super viewDidAppear:animated]; no super
}
EXC_BAD_ACCESS
è un errore di memoria. Probabilmente stai tentando di utilizzare un oggetto che è già stato rilasciato / deallocato. Questa risposta fornisce alcuni suggerimenti per il debug di questi problemi: