"Wait_fences: no se pudo recibir respuesta: 10004003"?

94

Recibo este error críptico la primera vez (y solo la primera vez) que mi vista se carga debido a la siguiente línea de código:

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

Hay un retraso notable (~ 3 - 4 segundos, incluso en el simulador) debido a esto que hace que mi aplicación no responda. ¿Alguien sabe cómo arreglar esto? No puedo encontrar ninguna documentación sobre él en el sitio de Apple, ni ninguna solución aquí o en Google.

Curiosamente, ocurre la situación opuesta si pongo la línea en -viewDidAppear:lugar de -viewWillAppear:; es decir, en lugar de imprimir el error solo la primera vez que se muestra el teclado y nunca más, el error no se imprime la primera vez sino todas las veces posteriores. Esto me está causando un gran dolor de cabeza.

Miguel
fuente

Respuestas:

103

Anule -viewDidAppear:, no -viewWillAppear, y asegúrese de llamar [super viewDidAppear:]. No debe realizar animaciones cuando no esté en la pantalla ("aparecerá"). Y los -viewDidAppear:médicos explican que debes llamar superporque ellos tienen sus propias cosas que hacer.

Rob Napier
fuente
Esto no es tan receptivo como me gustaría (todavía hay un ligero retraso en mostrar el teclado cada vez), pero parece funcionar.
Michael
1
Sé del retraso del que estás hablando. Lo he visto en muchas aplicaciones. Puede intentar llamar a -becomeFirstResponder antes (en lugar de después) de llamar a - [super viewDidAppear:] si aún no lo ha hecho. Es posible que esto no tenga ningún impacto, pero podría hacer que la animación comience en el mismo bucle de eventos en lugar del siguiente. No he experimentado con esto todavía para confirmar.
Rob Napier
14
Esto no soluciona el problema. Si arroja un UIAlertSheet en viewDidAppear, después de llamar a [super viewDidAppear: animated], terminará con el mismo mensaje, siempre. Sin embargo, si lo vomita después, digamos en respuesta a una ibacción, no hay problema. así que performWithSelector es probablemente la forma de solucionarlo, o puede ignorar el mensaje, de cualquier manera esto parece ser un error del SDK, no un problema con su código.
Billy Gray
9
@Billy, lanzar un UIAlertSheet antes de que se realicen las animaciones probablemente causaría el mismo problema. En cualquier caso, está colocando una hoja dentro de viewDidAppear probablemente sea demasiado pronto y probablemente debería usar performSelector: afterDelay: para empujar UIAlertSheet al siguiente ciclo. Eso no es un error en el SDK, aunque los detalles aquí están mal documentados. Realizar animaciones en -viewWillAppear fue el error en el código original. En cualquier caso, no debe ignorar el mensaje. Puede dar lugar a artefactos visuales extraños (un extraño deslizamiento lateral de la animación).
Rob Napier
22

Recibí un error similar cuando rápidamente:

  1. Descartar una vista modal
  2. Actualizar la vista principal
  3. Presentando una nueva vista modal

Noté que solo lo estaba obteniendo en el simulador y no en el dispositivo. Además, estaba atrapado en un bucle infinito.

Mi solución fue retrasar la presentación de la nueva vista modal. Parece que la actualización rápida de la jerarquía de vistas provocó algunas condiciones de carrera en el código de Apple.

Con eso en mente, intente esto:

     - (void)viewDidAppear:(BOOL)animated{

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

Es posible que tenga problemas al presentar el teclado para un UITextField que aún no está en la pantalla. Esto puede estar causando problemas similares al mío.

Además, hace una pausa para que la jerarquía se actualice antes de presentar el teclado, por si acaso.

Espero que esto ayude.

Corey Floyd
fuente
3
Para los problemas que tenías con los modales, ¿esperaste a que el modal terminara de descartarse antes de presentar el nuevo modal? En lugar de esperar un período de tiempo arbitrario y esperar que se complete, puede saberlo anulando -viewDidDisappear en modalViewController. Eso puede volver a llamar al -parentViewController del modal, o podría publicar una notificación. La clave es entender que pedir que se descarte algo no significa que se haya ido todavía, y no debe animar cosas una encima de la otra en general. -viewWill / DidDisappear es generalmente la mejor manera de saber con certeza cuándo suceden las cosas.
Rob Napier
La primera vista modal fue el selector de fotos, y yo manejo todo dentro del método de devolución de llamada del selector de fotos. Tiene razón, debería haber colocado el código para iniciar la siguiente vista modal dentro de viewDdiAppear. esa es una mejor solución y probablemente solucionaría el problema independientemente de la plataforma.
Corey Floyd
12

Compruebe que solo está interactuando con la interfaz de usuario en el hilo principal. Recibí wait_fences: failed to receive reply: 10004003mientras estaba sentado allí esperando que se mostrara un UIAlertView durante unos 5 segundos porque el código relevante se ejecutó en un hilo de fondo. Puede asegurarse colocando su código en bloque y enviándolo al hilo 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];
    }
});
diacodélico
fuente
9

Después de probar todo lo que pude encontrar en Google y nada de eso funcionó, esto es lo que me resolvió el problema. La clave es que estoy haciendo estas cosas en el método delegado willDismissWithButtonIndex. Antes lo hacía en otra parte.

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

Si tiene la siguiente línea en viewDidLoad, puede causar este mensaje. Comente la siguiente línea.

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

(En su lugar, puede desactivar la barra de estado del archivo plist de la aplicación).

rlcoder
fuente
7

Después de algunas pruebas, la gran regla es: "No realizar animaciones antes de la salida animada o del espectáculo animado".

Por ejemplo:

  • no llame -dismissModalViewControllerAnimated:YESdespués de la devolución de llamada de delegación de un (espere el desvanecimiento de la vista de alerta antes de hacer esto usando la devolución de llamada)UIAlertView -alertView:willDismissWithButtonIndex:-alertView:didDismissWithButtonIndex:
  • no intente mostrar el teclado ( becomeFirstResponder) antes de que su controlador de vista esté en pantalla.

Pueden pasar cosas malas.

Espero que te sea de utilidad ;-)

nverinaud
fuente
Estaba usando clickedButtonAtIndex y haría un montón de campos de texto antes de que se descartara la vista de alerta. ¡Cambiarlo a didDismissWithButtonIndex ciertamente ayudó a deshacerse de esas advertencias! ¡Gracias!
Nitin Alabur
5

Esto funcionó para que el teclado se mostrara de inmediato, sin animación ni demora.

Sea textFielduna variable de instancia de MyViewController(una subclase de UIViewController).

Llamar [textField becomeFirstResponder]en initWithNibName:bundle:(para una subclase de UIViewController) o initWithStyle:(para una subclase de UITableViewController), no en viewDidLoad. P.ej:

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

O llámelo justo después de inicializar, pero antes de presionar UIViewController. P.ej:

MyViewController *viewController = [[MyViewController alloc] init];
[viewController.textField becomeFirstResponder];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
ma11hew28
fuente
Interesante. ¿Estás seguro de que esto funciona todo el tiempo? Mi preocupación es que no hace referencia view, por lo que no es seguro que se haya cargado el archivo nib. Si textFieldes un IBOutlet, entonces pensaría que sería nulo en este momento.
Rob Napier
5

Has hecho [textfield becomeFirstResponder];

Y después de obtener el valor de textfield en su código, hágalo [textfield resignFirstResponder];. Eso te ayudará, creo.

Gani
fuente
4

Si está ejecutando el iPhone Simulator 4.0 actual, este mensaje de error aparece con frecuencia al girar la pantalla (o al animar después de girar la pantalla) acompañado de un retraso de 1-2 segundos en las animaciones.

Es un error en esta versión del Simulador y debería corregirse pronto.

Matt Gallagher
fuente
gracias por la información sobre el error del simulador de iOS4. para el mismo proyecto, el wait_fencesmensaje no apareció en el simulador 3.1
ohho
3

Consulte aquí para obtener más información: http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/17373-wait_fences-failed-receive-reply-10004003-a.html

Tu problema está relacionado.

Andrew Johnson
fuente
Gracias por la ayuda, pero lamentablemente no puedo encontrar una solución para mi problema en esa página. "Parece ocurrir cuando se crea una subvista (por ejemplo, UIAlertView) antes que su vista principal / supervista". Esto no debería estar sucediendo en el código anterior, ¿verdad?
Michael
3

anular viewDidappear, no viewWillAppear:

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

Puedo simular este uno a uno por medio de este código UIAlertView.

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

Cuando NSLocalizedString no está definido en el archivo Localizable.strings, la búsqueda de los textos llevará mucho tiempo, por lo que se mostrará la alerta y se mostrará "wait_fences: no se pudo recibir la respuesta: 10004003".

Para mí solo tuve que agregar los textos a los archivos Localizable.strings y mis problemas se resolvieron. ¿Quizás este sea también el caso de otras ocurrencias?

Vincent
fuente
1

También con UIAlertView. Lo que me resolvió fue tener la renuncia como se muestra a continuación, como Warehouselabs mencionó anteriormente.

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

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

Los otros delegados de UIAlertViewDelegate no solucionaron el problema.

Marcus
fuente
1

El problema es que hay una condición de carrera en el código de Apple. Normalmente, esto tiene que ver con actualizaciones incorrectas de la interfaz de usuario.

En mi experiencia, no ha llamado al super en viewDidAppear, viewWillAppear, etc. O intenta mostrar un UIAlertView en viewDidLoad o viewWillAppear.

Cuando agrega un UIAlertView, el marco necesita una referencia a su vista principal. Pero si está en viewWillAppear o viewDidLoad, la vista no se muestra realmente ... Debería considerar mover el código a viewDidAppear donde la vista está lista para ser utilizada por UIAlertView.

Hola Mundo
fuente
0

¿El campo de texto está contenido en esa vista o en algo más? Solo puede enviar el 'BecomeFirstRepsonder' a algo que esté contenido directamente dentro de esa vista. Si está almacenado en algún otro componente del widget, no debe establecer el estado del primer respondedor en este widget, sino en el widget que se está creando. Por ejemplo, si está agregando el campo de texto a una vista de alerta, debido a que el programa ocurre de forma asincrónica, es posible que no esté activo para cuando llame a BecomeFirstResponder. (Idealmente, tendría su propia clase de vista de alerta y definiría el campo de texto dentro de eso, y cuando esa vista reciba viewDidAppear, establecería el campo de texto como primer respondedor en ese punto).

AlBlue
fuente
0

También recibo el mensaje wait_fences: failed to receive reply: 10004003y mis métodos viewWill...y viewDid...no hacen nada más que enviar mensajes a super. En mi caso, sucede cuando tengo una UIAlertViewvisualización en mi GameViewControllery el usuario presiona el botón del dispositivo redondo del iPhone y luego regresa a la aplicación. Esto parece fuera de mis manos.

SK9
fuente
0

La vista de alerta o las hojas de acciones deben mostrarse en los subprocesos principales ... por lo que si realiza alguna conexión síncrona y realiza esa operación en otro subproceso y muestra alertas sobre la base de la salida que recibió de esa operación, recibirá este mensaje de error wait_fences: no se pudo recibir respuesta: 10004003. Puedes hacer algo como ...

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

y mostrar alertas en el método handleOutput pasando la cadena de respuesta de salida como parámetro.

Vishal Singh
fuente
0

¡La solución está aquí!

Tuve el mismo error, ahora tengo la solución, esto puede ayudarte.

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