"Wait_fences: impossibile ricevere la risposta: 10004003"?


94

Ottengo questo errore criptico la prima volta (e solo la prima volta) la mia vista viene caricata a causa della seguente riga di codice:

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

C'è un notevole ritardo (~ 3 - 4 secondi, anche sul simulatore) dovuto a questo che fa sentire la mia app non rispondere. Qualcuno sa come risolvere questo problema? Non riesco a trovare alcuna documentazione su di esso sul sito Apple o alcuna soluzione qui o su Google.

Stranamente, la situazione opposta accade se metto la linea -viewDidAppear:invece di -viewWillAppear:; ovvero, invece di stampare l'errore solo la prima volta che viene visualizzata la tastiera e mai più, l'errore non viene stampato la prima volta ma ogni volta dopo. Questo mi sta causando un forte mal di testa.

Risposte:


103

Ignora -viewDidAppear:, no -viewWillAppear, e assicurati di chiamare [super viewDidAppear:]. Non dovresti eseguire animazioni quando non sei sullo schermo ("apparirà"). E i -viewDidAppear:documenti spiegano che devi chiamare superperché hanno le loro cose da fare.


Questo non è reattivo come vorrei (c'è ancora un leggero ritardo che mostra la tastiera ogni volta), ma sembra che faccia il trucco.
Michael,

1
Conosco il ritardo di cui parli. L'ho visto in molte app. Potresti provare a chiamare -becomeFirstResponder prima (invece che dopo) chiamare - [super viewDidAppear:] se non lo sei già. Ciò potrebbe non avere alcun impatto, ma l'animazione potrebbe iniziare nello stesso ciclo di eventi anziché in quello successivo. Non l'ho ancora sperimentato per confermare.
Rob Napier,

14
Questo non risolve il problema. Se lanci un UIAlertSheet in viewDidAppear, dopo aver chiamato [super viewDidAppear: animated], ti ritroverai con lo stesso messaggio, ogni volta. se, tuttavia, lo lanci dopo, dì in risposta a un ibaction, nessun problema. quindi performWithSelector è probabilmente il modo per risolvere il problema, oppure potresti ignorare il messaggio, in entrambi i casi questo sembra essere un bug dell'SDK, non un problema con il tuo codice.
Billy Grey

9
@Billy, lanciare un UIAlertSheet prima che le animazioni siano state fatte probabilmente causerebbe lo stesso problema. In ogni caso, stai mettendo un foglio all'interno di viewDidAppear probabilmente è troppo presto e probabilmente dovresti usare performSelector: afterDelay: per spingere l'UIAlertSheet al ciclo successivo. Non è un bug nell'SDK, anche se i dettagli qui sono scarsamente documentati. L'esecuzione di animazioni in -viewWillAppear era il bug nel codice originale. In entrambi i casi, non dovresti ignorare il messaggio. Può portare a strani artefatti visivi (uno strano scorrimento laterale dell'animazione).
Rob Napier,


22

Ho ricevuto un errore simile quando rapidamente:

  1. Chiusura di una visualizzazione modale
  2. Aggiornamento della vista principale
  3. Presentazione di una nuova visualizzazione modale

Ho notato che lo stavo ricevendo solo nel simulatore e non sul dispositivo. Inoltre, mi trovavo intrappolato in un ciclo infinito.

La mia soluzione era ritardare la presentazione della nuova visualizzazione modale. Sembra che l'aggiornamento rapido della gerarchia di visualizzazione abbia causato un po 'di race condition nel codice di Apple.

Con questo in mente, prova questo:

     - (void)viewDidAppear:(BOOL)animated{

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

Potresti avere problemi a presentare la tastiera per un UITextField che non è ancora sullo schermo. Ciò potrebbe causare problemi simili ai miei.

Inoltre, ti fermi dando alla gerarchia il tempo di aggiornarsi prima di presentare la tastiera, per ogni evenienza.

Spero che questo ti aiuti.


3
Per i problemi che stavi riscontrando con le modali, hai aspettato che il modale finisse di chiudere prima di presentare il nuovo modale? Invece di aspettare un periodo di tempo arbitrario e sperare che sia completato, puoi saperlo sovrascrivendo -viewDidDisappear nel modalViewController. Questo può richiamare il modal's -parentViewController o inviare una notifica. La chiave è capire che chiedere qualcosa da ignorare non significa che non sia ancora finito, e non dovresti animare le cose l'una sull'altra in generale. -viewWill / DidDisappear è generalmente il modo migliore per sapere con certezza quando accadono le cose.
Rob Napier,

La prima visualizzazione modale era il selettore di foto e gestisco tutto all'interno del metodo di richiamata del selettore di foto. Hai ragione, avrei dovuto inserire il codice per avviare la prossima visualizzazione modale all'interno di viewDdiAppear. questa è una soluzione migliore e molto probabilmente risolverebbe il problema indipendentemente dalla piattaforma.
Corey Floyd,

12

Verifica di interagire solo con l'interfaccia utente sul thread principale. Ho ottenuto wait_fences: failed to receive reply: 10004003mentre ero seduto lì in attesa che UIAlertView venisse visualizzato per circa 5 secondi perché il codice pertinente è stato eseguito su un thread in background. Puoi assicurarti mettendo il tuo codice in blocco e inviandolo al thread principale:

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];
    }
});

9

Dopo aver provato tutto ciò che potevo trovare su Google e niente di tutto ciò funzionava, questo è ciò che ha risolto il problema per me. La chiave è che sto facendo queste cose nel metodo delegato willDismissWithButtonIndex. Prima lo facevo altrove.

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [myTextField resignFirstResponder];
    [myTextField removeFromSuperview];  
    [myTextField release];  
}

8

Se hai la seguente riga in viewDidLoad, può causare questo messaggio. Commenta la riga seguente.

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

(Puoi invece disabilitare la barra di stato dal file plist dell'applicazione).


7

Dopo pochi test la regola principale è: "Non eseguire animazioni prima del licenziamento animato o dello spettacolo animato".

Per esempio:

  • non chiamare -dismissModalViewControllerAnimated:YESdopo la richiamata di delega di un (attendere la dissolvenza in uscita dalla visualizzazione degli avvisi prima di farlo utilizzando la richiamata)UIAlertView -alertView:willDismissWithButtonIndex:-alertView:didDismissWithButtonIndex:
  • non provare a mostrare la tastiera ( becomeFirstResponder) prima che il controller della vista sia sullo schermo.

Possono accadere cose brutte.

Spero che sia utile ;-)


Stavo usando clickedButtonAtIndex e avrei compilato un mucchio di campi di testo prima che l'avviso venisse chiuso. Il passaggio a didDismissWithButtonIndex ha sicuramente aiutato a sbarazzarsi di quegli avvertimenti! Grazie!
Nitin Alabur

5

Questo ha funzionato per me per far sì che la tastiera si mostrasse immediatamente, senza animazioni o ritardi.

Sia textFielduna variabile di istanza di MyViewController(una sottoclasse di UIViewController).

Chiama [textField becomeFirstResponder]in initWithNibName:bundle:(per una sottoclasse di UIViewController) o initWithStyle:(per una sottoclasse di UITableViewController), non in viewDidLoad. Per esempio:

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

Oppure chiamalo subito dopo l'inizializzazione ma prima di premere il UIViewController. Per esempio:

MyViewController *viewController = [[MyViewController alloc] init];
[viewController.textField becomeFirstResponder];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];

Interessante. Sei sicuro che funzioni sempre? La mia preoccupazione è che non fai riferimento view, quindi non è sicuro che il file pennino sia stato caricato. Se textFieldè un IBOutlet, allora penso che sarebbe zero a questo punto.
Rob Napier

5

Hai fatto [textfield becomeFirstResponder];

E dopo aver ottenuto il valore da textfield nel codice, eseguire [textfield resignFirstResponder];. Questo ti aiuterà, penso.


4

Se stai utilizzando l'attuale iPhone Simulator 4.0, questo messaggio di errore appare frequentemente quando si ruota lo schermo (o durante l'animazione dopo aver ruotato lo schermo) accompagnato da 1-2 secondi di ritardo nelle animazioni.

È un bug in questa versione del simulatore e dovrebbe essere risolto presto.


grazie per informazioni sul bug del simulatore iOS4. per lo stesso progetto, il wait_fencesmessaggio non è stato visualizzato nel simulatore 3.1
ohho

3

Grazie per l'aiuto, ma sfortunatamente non riesco a trovare una soluzione al mio problema su quella pagina. "Sembra che si verifichi quando una vista secondaria (ad es. UIAlertView) viene creata prima della sua vista principale / super." Questo non dovrebbe accadere nel codice sopra, giusto?
Michael,

3

override viewDidappear, non viewWillAppear:

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

3

Posso simulare questo uno contro uno tramite questo codice UIAlertView.

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

Quando le NSLocalizedString non sono definite nel file Localizable.strings, la ricerca dei testi richiederà molto tempo, quindi verrà visualizzato l'avviso e verrà visualizzato "wait_fences: failed to receive reply: 10004003".

Per me dovevo solo aggiungere i testi ai file Localizable.strings ei miei problemi sono stati risolti. Forse è così anche per altri avvenimenti?


1

Anche con UIAlertView. Ciò che lo ha risolto per me è stato avere le dimissioni come sotto, come menzionato in precedenza dai magazzinieri.

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

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

Gli altri delegati di UIAlertViewDelegate non hanno risolto il problema.


1

Il problema è che c'è una condizione di gara nel codice di Apple. Di solito, questo ha a che fare con aggiornamenti dell'interfaccia utente errati.

Nella mia esperienza, non hai chiamato il super in viewDidAppear, viewWillAppear ecc. Oppure provi a visualizzare un UIAlertView in viewDidLoad o viewWillAppear.

Quando aggiungi un UIAlertView, il framework necessita di un riferimento alla tua vista padre. Ma se sei in viewWillAppear o viewDidLoad, la vista non è effettivamente visualizzata ... Dovresti considerare di spostare il codice in viewDidAppear dove la vista è pronta per essere usata da UIAlertView.


0

Il campo di testo è contenuto in quella vista o in qualcos'altro? È possibile inviare solo "diventaFirstRepsonder" a qualcosa che è contenuto direttamente in quella vista. Se è memorizzato in qualche altro componente widget, non dovresti impostare lo stato del primo risponditore in questo widget, ma piuttosto nel widget che viene creato. Ad esempio, se stai aggiungendo il campo di testo a una visualizzazione degli avvisi, poiché lo spettacolo avviene in modo asincrono, potrebbe non essere attivo nel momento in cui chiami diventaFirstResponder. (Idealmente, dovresti avere la tua classe di visualizzazione degli avvisi e definire il campo di testo al suo interno, e quando quella vista riceve il viewDidAppear, dovresti impostare il campo di testo come primo risponditore a quel punto.)


0

Ricevo anche il messaggio wait_fences: failed to receive reply: 10004003e i miei metodi viewWill...e viewDid...non fanno altro che inviare messaggi a super. Nel mio caso succede quando ho una UIAlertViewvisualizzazione nel mio GameViewControllere l'utente invece preme il pulsante rotondo del dispositivo iPhone e poi torna all'app. Questo sembra fuori dalle mie mani.


0

Alertview o actionheets dovrebbero essere mostrati sui thread principali ... quindi se stai effettuando connessioni sincrone ed esegui quell'operazione su un altro thread e mostri avvisi sulla base dell'output che hai ricevuto da quell'operazione, riceverai questo messaggio di errore wait_fences: non riuscito ricevere risposta: 10004003. Puoi fare qualcosa come ...

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

e mostra gli avvisi nel metodo handleOutput passando la stringa di risposta di output come parametro.


0

La soluzione è qui!

Ho avuto lo stesso errore, ora ho la soluzione, questo potrebbe aiutarti.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
  [self performSelector:@selector(YOUR_METHOD) withObject:nil afterDelay:0.1];
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.