Question

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 que cela a 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! Il semble donc que ce soit 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];  
}
Était-ce utile?

La solution

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! Il semble donc que ce soit 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];  
}

Autres conseils

Je crois que j'ai reproduit la même erreur dans iOS 4. Dans mon application, le blocage s’est produit de manière constante 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 sur un 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 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:

*** Arrêt de l'application en raison d'une exception non interceptée 'NSInternalInconsistencyException', raison: 'Tentative 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. '

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 l'intégralité de la trace de la pile:

** 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

J'espère que cela vous aidera.

** Comme cela a été dit précédemment, 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];
    }

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 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.

J'ai rencontré la même exception

  

Arrêt de l'application en raison d'une exception non interceptée 'NSInternalInconsistencyException', raison: 'Tentative 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 ensuite constaté que plusieurs IBActions étaient 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!

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

Définissez des points d'arrêt et suivez-les jusqu'au crash ...

J'ai eu une erreur similaire en cliquant sur un UIButton pour ouvrir une vue modale . J'ai remplacé le programme d'écoute de UIButton de UIControlEventAllEvents par UIControlEventTouchUpInside . Fondamentalement, la vue modale était activée dans Touch Down Inside , puis à nouveau sur Touch Up Inside .

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

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

et le nom du fichier .xib actuel.

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

Créer un nouveau projet XCode "Utilitaire". Dans le 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 activée à droite une façon. Dès que vous appuyez sur le bouton "Terminé". Bouton sur la vue de côté, vous reviendrez à la vue principale qui déclenche viewDidAppear à nouveau et retourne directement à la flipside- vue. Dès que la vue inverse est affichée, l'application s'arrête - pas de mémoire les désallocateurs sont appelés - 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 l'exception, donc j'ai dépouillé le code au minimum ...

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

Cordialement, Tobias

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û au fait que UIWindowController essaie de parler de loader qui a été publié depuis (à la fin de la routine que vous avez postée).

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 rejetée à la fin du chargement. Dans mon cas, le problème provenait du fait que dès que la vue de chargement avait été rejetée, viewDidAppear était à nouveau appelée et tentait de présenter à nouveau la vue de chargement, ce qui a probablement déclenché le blocage. 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 vous aidera ...

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 un un bogue dans Xcode et pas nécessairement tout ce que nous avons fait de mal dans nos styles de codage.

Eu 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 je réalisais presentModalViewController directement après une modale UIPickerViewController.

Je viens d'avoir ce problème et il s'est avéré que mon problème était dû au fait que j'étais désintéressé de mon délégué au protocole.

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 qu'il a

[super viewDidAppear animated];

ce qui signifie qu'il appellera à nouveau viewDidAppear de votre contrôleur de vue principale, comme ça il ira 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

}

EXC_BAD_ACCESS est une erreur de mémoire. Vous essayez probablement d'utiliser un objet qui a déjà été libéré / désalloué. Cette réponse donne quelques astuces pour résoudre ces problèmes:

Débogage EXC_BAD_ACCESS

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top