2008-10-03 15 views
5

Si generar un nuevo subproceso, y luego dentro de ella empujo un nuevo controlador en mi UINavigationController, utilizando código como este ...interacción NSThread y UIViewController

(a) que no trabaja

-(void)myCallbackInThread 
{ 
    // move on... 
    UIApplication* app = [UIApplication sharedApplication]; 
    [app changeView]; 
} 

entonces encuentro que la vista aparece, pero no responde a la entrada del usuario.

Si cambio el código como este

(b) trabajar

-(void)myCallbackInThread 
{ 
    // move on... 
    UIApplication* app = [UIApplication sharedApplication]; 
    [app performSelectorOnMainThread:@selector(moveToMain) withObject:nil waitUntilDone:FALSE]; 
} 

Entonces todo funciona bien.

¿Algún indicio de por qué?

+0

¿Está obteniendo algo en la ventana de la consola? He encontrado con subprocesos en el iPhone si estás haciendo algo gracioso que genera mensajes de registro. – Lounges

Respuesta

2

En su caso, realmente depende de lo que ocurra en [app changeView], pero la razón por la que deja de responder es muy probable que no tenga eventos de ejecución de bucle en su nuevo hilo secundario (más sobre esto más adelante). En general, sin embargo, es una muy mala idea actualizar la GUI desde un hilo secundario. Como ya has descubierto, todos estos eventos deberían pasar por el hilo principal.

La razón principal de que su segundo ejemplo funcione y no el primero es que UIApplication configura y maneja el bucle de ejecución y el despachador de eventos para usted en el hilo principal. Por lo tanto, cuando se llama a performSelectorInMainThread, el selector se envía al ciclo de ejecución principal, que es capaz de manejar la entrada de su GUI y otros eventos. El despachador de eventos también es ejecutado y administrado por UIApplication en el hilo principal.

Por lo tanto, básicamente, no realice ninguna actividad de administración de la GUI en una secuencia secundaria. Despacharlos al hilo principal. Y si necesita procesamiento en un hilo secundario (para cosas como temporizadores o llamadas asincrónicas, etc.) luego debe iniciar y administrar su propio bucle de ejecución en ese hilo (consulte NSRunLoop para obtener más información sobre la administración de su bucle en ejecución).

2

acaba de encontrar esto en los documentos de roscado iPhone

Si la aplicación tiene una interfaz gráfica usuario, se recomienda que recibe eventos relacionados con el usuario y iniciar actualizaciones de la interfaz de hilo principal de la aplicación . Este enfoque ayuda a evitar la sincronización problemas asociados con el manejo del usuario eventos y el contenido de la ventana de dibujo. Algunos marcos, como Cocoa, generalmente requieren este comportamiento, pero también tiene la ventaja de simplificando la lógica para administrar su interfaz de usuario.

Todavía no veo lo que realmente causaría que se muestre algo pero no pueda recibir la entrada del usuario, pero lo seguiré en el futuro.

2

Como dice la documentación, "Si no está seguro acerca de una operación gráfica en particular, planee hacerlo a partir de su hilo principal".

Una buena regla de oro a seguir es que, si una clase no está explícitamente documentada como segura para subprocesos, entonces probablemente no lo sea. Además, el código que no está documentado como seguro para subprocesos puede no fallar rápidamente cuando se utiliza con varios subprocesos, pero puede mostrar un comportamiento no definido, como viste.

0

Casi ninguno del código de UI en UIKit o AppKit es seguro para la rosca. Cómo falla es irrelevante, porque si te preocupa cómo falla, estás haciendo algo que resultará en todo tipo de errores extraños que cambiarán sutilmente entre diferentes versiones del sistema operativo de todos modos.

Mi mejor consejo es no usar elementos de subprocesos de fondo a menos que los documentos indiquen que es seguro.

Cuestiones relacionadas