"Wait_fences: échec de réception de la réponse: 10004003"?

94

J'obtiens cette erreur cryptique la première fois (et seulement la première fois) ma vue est chargée en raison de la ligne de code suivante:

- (void)viewWillAppear:(BOOL)animated
{
    [textField becomeFirstResponder];
}

Il y a un retard notable (~ 3 à 4 secondes, même sur le simulateur) à cause de cela qui fait que mon application ne répond pas. Est-ce que quelqu'un sait comment réparer ceci? Je ne trouve aucune documentation à ce sujet sur le site d'Apple, ni aucune solution ici ou sur Google.

Étrangement, la situation inverse se produit si je mets la ligne au -viewDidAppear:lieu de -viewWillAppear:; c'est-à-dire qu'au lieu d'imprimer l'erreur uniquement la première fois que le clavier est affiché et plus jamais, l'erreur n'est pas imprimée la première fois mais à chaque fois après. Cela me cause un mal de tête majeur.

Michael
la source

Réponses:

103

Remplacez -viewDidAppear:, non -viewWillAppearet assurez-vous d'appeler [super viewDidAppear:]. Vous ne devez pas effectuer d'animations lorsque vous n'êtes pas à l'écran ("apparaîtra"). Et les -viewDidAppear:documents expliquent que vous devez appeler superparce qu'ils ont leurs propres choses à faire.

Rob Napier
la source
Ce n'est pas aussi réactif que je le souhaiterais (il y a toujours un léger retard montrant le clavier à chaque fois), mais cela semble faire l'affaire.
Michael le
1
Je connais le décalage dont vous parlez. Je l'ai vu dans de nombreuses applications. Vous pouvez essayer d'appeler -becomeFirstResponder avant (plutôt qu'après) d'appeler - [super viewDidAppear:] si vous ne l'êtes pas déjà. Cela peut n'avoir aucun impact, mais peut démarrer l'animation dans la même boucle d'événements plutôt que dans la suivante. Je n'ai pas encore expérimenté cela pour confirmer.
Rob Napier le
14
Cela ne résout pas le problème. Si vous lancez une UIAlertSheet dans viewDidAppear, après avoir appelé [super viewDidAppear: animated], vous vous retrouvez avec le même message, à chaque fois. si, cependant, vous le jetez après, disons en réponse à une ibaction, pas de problème. donc performWithSelector est probablement le moyen de corriger, ou vous pouvez ignorer le message, de toute façon cela semble être un bogue du SDK, pas un problème avec votre code.
Billy Gray
9
@Billy, lancer une feuille UIAlertSheet avant la fin des animations causerait probablement le même problème. Dans tous les cas, vous mettez une feuille à l'intérieur de viewDidAppear est probablement trop tôt et vous devriez probablement utiliser performSelector: afterDelay: pour pousser UIAlertSheet à la boucle suivante. Ce n'est pas un bogue dans le SDK, bien que les détails ici soient mal documentés. L'exécution d'animations dans -viewWillAppear était le bogue dans le code d'origine. Dans les deux cas, vous ne devez pas ignorer le message. Cela peut conduire à des artefacts visuels étranges (un étrange glissement latéral de l'animation).
Rob Napier
22

J'obtenais une erreur similaire lorsque rapidement:

  1. Ignorer une vue modale
  2. Mise à jour de la vue principale
  3. Présentation d'une nouvelle vue modale

J'ai remarqué que je ne l'obtenais que dans le simulateur et non sur l'appareil. De plus, je me faisais prendre dans une boucle infinie.

Ma solution a été de retarder la présentation de la nouvelle vue modale. Il semble que la mise à jour rapide de la hiérarchie des vues ait causé une certaine condition de concurrence dans le code d'Apple.

Dans cet esprit, essayez ceci:

     - (void)viewDidAppear:(BOOL)animated{

            [super viewDidAppear:animated];
            [textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];
  }

Vous rencontrez peut-être des problèmes pour présenter le clavier d'un UITextField qui n'est pas encore à l'écran. Cela peut causer des problèmes similaires aux miens.

En outre, vous faites une pause pour donner à la hiérarchie le temps de se mettre à jour avant de présenter le clavier, au cas où.

J'espère que cela t'aides.

Corey Floyd
la source
3
Pour les problèmes que vous rencontriez avec les modaux, avez-vous attendu que le modal ait fini de se fermer avant de présenter le nouveau modal? Plutôt que d'attendre une période de temps arbitraire et d'espérer qu'il est terminé, vous pouvez le savoir en remplaçant -viewDidDisappear dans le modalViewController. Cela peut rappeler le -parentViewController du modal ou publier une notification. La clé est de comprendre que demander quelque chose à rejeter ne signifie pas qu'il est encore parti, et vous ne devriez pas animer les choses les unes sur les autres en général. -viewWill / DidDisappear est généralement votre meilleur moyen de savoir avec certitude quand les choses se produisent.
Rob Napier du
La première vue modale était le sélecteur de photos, et je gère tout dans la méthode de rappel du sélecteur de photos. À votre droite, j'aurais dû placer le code pour lancer la prochaine vue modale dans viewDdiAppear. c'est une meilleure solution et résoudrait très probablement le problème quelle que soit la plate-forme.
Corey Floyd le
12

Vérifiez que vous n'interagissez qu'avec l'interface utilisateur sur le thread principal. Je suis wait_fences: failed to receive reply: 10004003resté assis là en attendant qu'un UIAlertView s'affiche pendant environ 5 secondes car le code correspondant a été exécuté sur un thread d'arrière-plan. Vous pouvez vous en assurer en mettant votre code en bloc et en l'envoyant au thread principal:

dispatch_async(dispatch_get_main_queue(), ^{
    if (!success) {
        // Inform user that import failed
        UIAlertView * importFailedAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ErrorTitle5", @"Import failed") 
                                                                     message:NSLocalizedString(@"Error5", @"Something went wrong") 
                                                                    delegate:nil 
                                                           cancelButtonTitle:NSLocalizedString(@"OK", nil) 
                                                           otherButtonTitles:nil];
        [importFailedAlert show];
    }
});
diachéélique
la source
9

Après avoir essayé tout ce que je pouvais trouver sur Google et que rien de tout cela ne fonctionnait, c'est ce qui a résolu le problème pour moi. La clé est que je fais ce genre de choses dans la méthode déléguée willDismissWithButtonIndex. Avant je le faisais ailleurs.

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [myTextField resignFirstResponder];
    [myTextField removeFromSuperview];  
    [myTextField release];  
}
entrepôt
la source
8

Si vous avez la ligne suivante dans viewDidLoad, cela peut provoquer ce message. Commentez la ligne suivante.

[[UIApplication sharedApplication] setStatusBarHidden:YES]; //This line should be commented

(Vous pouvez désactiver la barre d'état à partir du fichier plist de l'application à la place).

rlcoder
la source
7

Après quelques tests, la grande règle est la suivante: "Ne pas effectuer d'animation avant le licenciement animé ou le spectacle animé.".

Par exemple:

  • ne pas appeler -dismissModalViewControllerAnimated:YESaprès le rappel de délégation d'un (attendez le fondu hors de la vue d'alerte avant de faire cela en utilisant le rappel)UIAlertView -alertView:willDismissWithButtonIndex:-alertView:didDismissWithButtonIndex:
  • n'essayez pas d'afficher le clavier ( becomeFirstResponder) avant que votre contrôleur de vue soit à l'écran.

De mauvaises choses peuvent arriver.

J'espère que ce sera utile ;-)

Nverinaud
la source
J'utilisais clickedButtonAtIndex et je ferais un tas de champs de texte remplissant avant que l'alerte soit rejetée. Le passage à didDismissWithButtonIndex a certainement aidé à éliminer ces avertissements! Merci!
Nitin Alabur
5

Cela a fonctionné pour moi pour que le clavier se montre immédiatement, sans animation ni retard.

Laisser textField une variable d'instance de MyViewController(une sous-classe de UIViewController).

Appel [textField becomeFirstResponder]à initWithNibName:bundle:(pour une sous - classe de UIViewController) ou initWithStyle:(pour une sous - classe deUITableViewController ), non viewDidLoad. Par exemple:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        [textField becomeFirstResponder];
    }
    return self;
}

Ou appelez-le juste après l'initialisation mais avant d'appuyer sur le UIViewController. Par exemple:

MyViewController *viewController = [[MyViewController alloc] init];
[viewController.textField becomeFirstResponder];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
ma11hew28
la source
Intéressant. Êtes-vous sûr que cela fonctionne tout le temps? Ma préoccupation est que vous ne faites pas référence view, il n'est donc pas certain que le fichier nib ait été chargé. Si textFieldc'est un IBOutlet, alors je pense que ce serait nul à ce stade.
Rob Napier
5

Vous avez fait [textfield becomeFirstResponder];

Et après avoir obtenu la valeur de textfield dans votre code, faites [textfield resignFirstResponder];. Cela vous aidera, je pense.

Gani
la source
4

Si vous exécutez l'actuel iPhone Simulator 4.0, ce message d'erreur apparaît fréquemment lors de la rotation de l'écran (ou lors de l'animation après la rotation de l'écran) accompagné d'un décalage de 1 à 2 secondes dans les animations.

C'est un bogue dans cette version du simulateur et devrait être corrigé bientôt.

Matt Gallagher
la source
merci pour les informations sur le bogue du simulateur iOS4. pour le même projet, le wait_fencesmessage n'est pas
apparu
3

Voir ici pour plus d'informations: http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/17373-wait_fences-failed-receive-reply-10004003-a.html

Votre problème est lié.

Andrew Johnson
la source
Merci pour l'aide, mais malheureusement je ne trouve pas de solution à mon problème sur cette page. "Cela semble se produire lorsqu'une sous-vue (par exemple, UIAlertView) est créée avant sa vue parent / super." Cela ne devrait pas se produire dans le code ci-dessus, non?
Michael le
3

remplacer viewDidappear, pas viewWillAppear:

-(void) viewDidAppear:(BOOL) animated
{
 [super viewDidAppear:animated];
 [myTextField becomeFirstResponder];
}
Wagh
la source
3

Je peux simuler ce tête-à-tête au moyen de ce code UIAlertView.

   UIAlertView *alert = [[UIAlertView alloc]
                   initWithTitle:NSLocalizedString(@"defineTitle",@"defineTitle")
                         message:NSLocalizedString(@"defineBody", @"defineBody")
                        delegate:self
               cancelButtonTitle:NSLocalizedString(@"Ok", @"Ok")
               otherButtonTitles:nil];
   [alert show];

Lorsque les NSLocalizedString ne sont pas définis dans le fichier Localizable.strings, la recherche des textes prendra trop de temps, donc l'alerte s'affichera et le message «wait_fences: failed to receive reply: 10004003» sera affiché.

Pour moi, je n'avais qu'à ajouter les textes aux fichiers Localizable.strings et mes problèmes ont été résolus. Peut-être que c'est également le cas pour d'autres occurrences?

Vincent
la source
1

Également avec le UIAlertView. Ce qui a résolu le problème pour moi, c'est d'avoir la démission comme ci-dessous, comme Warehouselabs mentionné plus tôt.

- (void)didPresentAlertView:(UIAlertView *)alertView
{
    [txtListingPassword becomeFirstResponder];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [txtListingPassword resignFirstResponder];
}

Les autres délégués de UIAlertViewDelegate n'ont pas résolu le problème.

Marcus
la source
1

Le problème est qu'il y a une condition de concurrence dans le code d'Apple. Habituellement, cela a quelque chose à voir avec des mises à jour incorrectes de l'interface utilisateur.

Dans mon expérience, soit vous n'avez pas appelé le super dans viewDidAppear, viewWillAppear etc. Ou vous essayez d'afficher un UIAlertView dans viewDidLoad ou viewWillAppear.

Lorsque vous ajoutez un UIAlertView, l'infrastructure a besoin d'une référence à votre vue parent. Mais si vous êtes dans viewWillAppear ou viewDidLoad, la vue n'est pas réellement affichée ... Vous devriez envisager de déplacer le code vers viewDidAppear où la vue est prête à être utilisée par UIAlertView.

Bonjour le monde
la source
0

Le champ de texte est-il contenu dans cette vue ou dans quelque chose d'autre? Vous ne pouvez envoyer le 'devenirFirstRepsonder' qu'à quelque chose qui est contenu directement dans cette vue. S'il est stocké dans un autre composant de widget, vous ne devez pas définir le statut de premier répondeur dans ce widget, mais plutôt dans le widget en cours de création. Par exemple, si vous ajoutez le champ de texte à une vue d'alerte, parce que l'émission se déroule de manière asynchrone, il se peut qu'elle ne soit pas active au moment où vous appelez le devenirFirstResponder. (Idéalement, vous auriez votre propre classe de vue d'alerte et définiriez le champ de texte à l'intérieur, et lorsque cette vue reçoit le viewDidAppear, vous définissez le champ de texte comme premier répondeur à ce stade.)

AlBlue
la source
0

Je reçois également le message wait_fences: failed to receive reply: 10004003et mes méthodes viewWill...et viewDid...ne font rien d'autre qu'à envoyer des messages super. Dans mon cas, cela se produit lorsque j'ai un UIAlertViewaffichage dans mon GameViewControlleret que l'utilisateur appuie à la place sur le bouton rond de l'iPhone, puis revient à l'application. Cela semble hors de mes mains.

SK9
la source
0

Alertview ou actionsheets doivent être affichés sur les threads principaux ... donc si vous établissez des connexions synchrones et effectuez cette opération sur un autre thread et affichez des alertes sur la base de la sortie que vous avez reçue de cette opération, vous obtiendrez ce message d'erreur wait_fences: failed to recevoir la réponse: 10004003. Vous pouvez faire quelque chose comme ...

[self performSelectotOnMainThread:@selector(handleOutput:) withObject:output waitUntilDone:YES/NO];

et afficher les alertes dans la méthode handleOutput en passant la chaîne de réponse de sortie comme paramètre.

Vishal Singh
la source
0

La solution est là!

J'ai eu la même erreur, maintenant j'ai la solution, cela peut vous aider.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
  [self performSelector:@selector(YOUR_METHOD) withObject:nil afterDelay:0.1];
}
SachinVsSachin
la source