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];  
}
È stato utile?

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:

Debugging EXC_BAD_ACCESS

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top