2011-11-07 12 views
13

¿Está bien el uso de una notificación a la comunicación para regresar al hilo principal de una aplicación IOS? (cf performSelectorOnMainThread). Es decir, ¿hay gottcha para este propósito?¿está bien utilizar una notificación de comunicación para volver al hilo principal de una aplicación IOS? (cf performSelectorOnMainThread)

Antecedentes

  • quieren volver a llamar al hilo principal interfaz de usuario desde un subproceso en segundo plano (por ejemplo performSelectorInBackground)
  • podría utilizar performSelectorOnMainThread para comunicarse de vuelta, pero pregunto si es correcto usar una notificación?

Por ejemplo

[[NSNotificationCenter defaultCenter] postNotificationName:@"ModelChanged" object:self]; 

Respuesta

20

En realidad hay un gottcha; ¡te estrellarás al azar! Esa ha sido mi experiencia. Esto tiene que ver con el hecho de que el objeto que recibe la notificación lo hace en el mismo hilo que el remitente de la notificación.

Desde el Apple iOS Documentation on Notification Centers:

En una aplicación multiproceso, las notificaciones son siempre entregados en el hilo en el que se publicó la notificación, que puede no ser el mismo hilo en la que un observador en sí registrado.

Esto inevitablemente le causará dolores de cabeza.

Si la notificación está siendo recibida por algo en el hilo principal, he encontrado que aparecer en el hilo principal desde el hilo de fondo para emitir una notificación es la forma más segura de hacerlo. Es muy simple de hacer:

//Call this to post a notification and are on a background thread  
- (void) postmyNotification{ 
    [self performSelectorOnMainThread:@selector(helperMethod:) withObject:Nil waitUntilDone:NO]; 
} 

//Do not call this directly if you are running on a background thread. 
- (void) helperMethod{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"SOMENAME" object:self]; 
} 

Desafortunadamente esto introduce un acoplamiento sutil entre el emisor y el receptor en el que está modificando el remitente para acomodar el receptor.

Una solución aún mejor, como señala XJones, es hacer que el remitente envíe la notificación en cualquier tema que decida, y luego hacer al oyente responsable de usar el hilo apropiado para realizar cualquier acción que necesite.

Espero que haya sido útil.

+1

Hice referencia a este problema en un comentario en mi respuesta. No me gusta su solución exactamente a/c del acoplamiento entre el objeto que publica la notificación y el observador. La publicación de objetos debe publicarse en el hilo que quiera. El receptor debe manejar la notificación en el hilo que necesita (por ejemplo, el receptor puede reenviar la notificación al hilo principal o cualquier otro hilo). Apple también usa este método en su código de muestra. – XJones

+0

Estoy completamente de acuerdo. He actualizado mi respuesta para reflejar este método. – PixelCloudSt

+0

@PixelCloudSt Entiendo el acoplamiento en este método, pero ¿cómo haré para que el receptor escuche en múltiples hilos? –

8

Sí, las notificaciones se pueden utilizar para este propósito. puede usar cualquier método que desee (protocolos, notificaciones, mensajes directos) para comunicarse entre objetos a través de hilos. El que elijas depende de lo que sientas que sea más apropiado. Las notificaciones son excelentes cuando el objeto que publica la notificación no sabe nada sobre los objetos que observan la notificación. Si envía un mensaje (por ejemplo, performSelectorOnMainThread), el objeto que envía el mensaje necesita conocer el objeto al que está enviando el mensaje (normalmente a través de un protocolo).

+0

bien gracias - He tenido algunos problemas (http://stackoverflow.com/questions/8032987/why-do-i-get-wait-fences-failed-to-receive-reply-for-this-code) y preguntándose si esta podría haber sido la razón – Greg

+1

bien, acaba de publicar una respuesta sobre eso. En general, considero que es mejor aplicar los requisitos de subprocesos en los controladores vs en el remitente. Por ejemplo, puedes asegurarte de que siempre publicas notificaciones en el hilo principal, pero esto es tedioso. El objeto de publicación no debería importarle.Al destinatario le importa y debe reenviar el mensaje al hilo principal, si corresponde. – XJones

Cuestiones relacionadas