web-dev-qa-db-fra.com

iPhone en panne lors de la présentation du contrôleur de vue modale

J'essaie d'afficher une vue modale immédiatement après qu'une autre vue a été présentée sous forme modale (la seconde est une vue de chargement qui apparaît).

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

Mais lorsque je le fais, je reçois un "Signal reçu du programme:" EXC_BAD_ACCESS "." Erreur.

La trace de la pile est:

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

Des idées? Je suis totalement perplexe! La vue de chargement est vide, donc il ne se passe absolument rien qui cause l'erreur. Est-ce quelque chose à voir avec le lancement modal de 2 vues dans la même boucle d'événement ou quelque chose?

Merci,

Mike

Edit: Très étrange ... Je l'ai légèrement modifié pour que la vue de chargement s'affiche après un petit délai, et cela fonctionne bien! Cela semble donc être quelque chose dans la même boucle d'événement!

- (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];  
}
30
Michael Waterfall

Je l'ai légèrement modifié pour que la vue de chargement s'affiche après un petit délai, et cela fonctionne bien! Cela semble donc être quelque chose dans la même boucle d'événement!

- (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];  
}
30
Michael Waterfall

Je crois que j'ai reproduit la même erreur dans iOS 4. Dans mon application, le blocage est survenu de manière cohérente lors de la tentative d'affichage d'une seconde vue modale immédiatement après la présentation d'une première vue modale. Je me suis battu pendant quelques heures pour devenir fou.

Après avoir lu les articles de ce fil de discussion, j'ai essayé de créer un exemple reproductible simple à l'aide du modèle d'application Barre de tabulation. J'ai pu utiliser UIImagePickerController pour afficher la première vue modale après avoir répondu à un clic de bouton dans "FirstViewController.m". Lorsque j'ai essayé de montrer à nouveau UIImagePickerController (après avoir traité le message imagePickerControllerDidCancel), l'application est tombée en panne avec la même erreur.

Sur l'appareil, il n'y avait tout simplement aucune idée de ce qui se passait. Cependant, lorsque j'ai exécuté le code sur le simulateur, j'ai eu la chance de recevoir ce message sur la console:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from to while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed'

Il semble donc que mon seul choix est de suivre les conseils du message d'erreur et d'attendre simplement que viewDidAppear (en utilisant un indicateur pour indiquer que je suis dans ce mode spécial)), puis de charger la deuxième vue modale.

Voici la trace de pile complète pour être complet:

 ** Pile d'appels au premier lancer: 
 (
 0 CoreFoundation 0x0238c919 __exceptionPreprocess + 185 
 1 libobjc.A.dylib 0x024da5de objc_exception_throw + 47 
 2 CoreFoundation 0x02345078 + [NSException levée: format: arguments:] + 136 
 3 Fondation 0x000ab8cf - [NSAssertionHandler handleFailureInMethod: objet: fichier: numéro de ligne: description:] + 116 
 4 UIKit 0x00544317 - [UIWindowController transition: fromViewController: toViewController: cible: didEndSelector:] + 212 [.________] ] 7 Fondation 0x0002fcea __NSFireDelayedPerform + 441 
 8 CoreFoundation 0x0236 dd43 __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 [.____. commencer + 53 

J'espère que cela t'aides.

5
Daniel

** Comme on l'a dit plus tôt, utilisez 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];
    }
4
user353877

Il est possible que si vous obtenez cela après avoir cliqué sur un bouton lié à votre code dans Interface Builder, vous avez deux actions liées à un seul bouton (peut-être si vous aviez une vue modale liée à un bouton, puis dupliqué le bouton et lié une autre vue modale). Cela va essayer de les renvoyer tous les deux et donc cela échouera avec ce message.

3
Simon

J'ai rencontré la même exception 

Arrêt de l'application en raison d'une exception non interceptée 'NSInternalInconsistencyException', raison: 'Tenter de commencer une transition modale de à alors qu'une transition est déjà en cours. Attendez que viewDidAppear/viewDidDisappear sache que la transition en cours est terminée. '

Comme suggéré précédemment, j'ai essayé de retarder la présentation d'une transition modale, mais cela n'a pas vraiment aidé. J'ai alors découvert que j'avais plusieurs IBActions connectées à l'événement TouchUpInside de mon bouton !!! . Dans mon cas, deux IBActions commenceraient: présenter un sélecteur de personnes de manière modale et présenter un sélecteur d’images de manière modale. Ceci explique le message d'erreur. Vérifiez si vous avez plusieurs IBActions connectées!

3
Eddy

J'ai eu une erreur similaire en cliquant sur une UIButton pour ouvrir un Modal View. J'ai changé l'auditeur UIButton's de UIControlEventAllEvents à UIControlEventTouchUpInside. En gros, il activait la vue modale sur Touch Down Inside, puis à nouveau sur Touch Up Inside.

1
Chris

J'ai eu le même problème en raison de l'inadéquation entre les noms dans

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

et le nom du fichier .xib réel.

1
Alexey Podlasov

Votre problème est probablement lié à la méthode qui décrit et présente celle dans laquelle viewDidAppear se trouve ou à la méthode init/viewDidLoad/viewWillAppear de LoadViewController.

Définissez des points de rupture et suivez-les jusqu'au crash ...

1
Jordan

Je pense que cette question a quelque chose à voir avec un problème que j'ai aussi rencontré. Il est très facile à reproduire:

Créez un nouveau projet XCode "Utilitaire". Dans le fichier FlipsideViewController.m , Vous insérez simplement la méthode suivante:

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

Si vous faites cela, démarrez l’application, la vue inversée sera alors activée De suite. Dès que vous appuierez sur le bouton "Terminé" sur la vue inversée, vous retournerez À la vue principale qui déclenchera viewDidAppear et reviendra directement à la vue inversée - . Dès que la vue inverse est affichée, l'application s'arrête - aucune mémoire Désallocatrice n'est appelée - c'est comme si vous aviez appuyé sur le bouton d'accueil.

Lorsque j'utilisais des propriétés supplémentaires dans ces vues, j'ai également une exception, . J'ai donc réduit le code au minimum ...

Je n'ai vraiment aucune idée de la nature réelle de ce problème ...

Cordialement, Tobias

1
Tobias

J'ai rencontré ce problème tout à l'heure et je l'ai corrigé à l'aide du sélecteur: suggestion afterDelay ci-dessus. Juste pour ajouter, j'ai compilé (sans le correctif) sous iPhone OS 4.0 beta, et NO CRASH! Ainsi, le bogue dans XCode semble avoir été corrigé dans la prochaine génération. Cela ne nous fait aucun bien aujourd'hui, mais, juste pour que vous le sachiez, c'est vraiment était un bogue dans Xcode et rien de ce que nous avons fait de mal dans nos styles de codage.

0
pulseft

Je viens d'avoir ce problème et il s'est avéré que mon problème était parce que j'étais dealloc mon délégué de protocole.

0
NixonsBack

J'ai eu un problème similaire en utilisant la même technique que vous pour implémenter une vue de chargement. Il se plantait lorsque la vue de chargement était fermée à la fin du chargement. Dans mon cas, le problème venait du fait que dès que la vue de chargement avait été fermée, viewDidAppear était à nouveau appelée et tentait de présenter le chargement. voir à nouveau, ce qui a probablement provoqué le crash. Je l'ai corrigé simplement en vérifiant si la vue de chargement avait été présentée auparavant:

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

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

Ensuite, j'ai défini needDisplayLoader sur NO avant de fermer la vue Loader

J'espère que cela t'aides...

0
Rom

Je pense que la raison de la boucle est que le nouveau contrôleur de vue que vous chargez a une méthode viewDidAppear par défaut et 

[super viewDidAppear animated];

ce qui signifie qu'il rappellera à nouveau viewDidAppear de votre contrôleur de vue principal, comme s'il se mettait en boucle

dans Viewcontroller, vous présentez une méthode comme celle-ci, sans super viewdidapper:

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

}
0
NSGodMode

Cela dépend vraiment de ce que font les routines de support pour viewDidAppear. Par exemple, si presentModalViewController:animated: ne conserve pas loader, le blocage peut être dû à la tentative de UIWindowController de parler de loader qui a depuis été publiée (à la fin de la routine que vous avez postée).

0
fbrereto

Avait exactement le même problème. Résolu avec ce qui est suggéré ci-dessus ...

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

Doit utiliser un délai de 0,5 seconde. Peut-être parce que j'effectuais presentModalViewController directement après une modale UIPickerViewController.

0
Nate Potter