2011-02-03 16 views
6

Mi clase de modelo tiene que obtener algunos datos de internet. Así que decidí ejecutarlo en otro hilo para que el ui no se congele. Así que cuando un objeto quiere algunos datos que pide primero el modelo usando un método de este tipo:Método de ejecución en el hilo principal de otro hilo

- (void)giveMeSomeData:(id)object withLabel:(id)label { 
objectAsking= object; 
theLabel= label; 
NSThread* thread= [[NSThread alloc] initWithTarget:self selector:@selector(getTheDataFromInternet) object:nil]; 
[thread start]; 
} 

- (void)getTheDataFromInternet { 
//getting data... 

theData= [dataFromInternet retain]; //this is the data the object asked for 
[self returnObjectToAsker]; 
} 

- (void)returnObjectToAsker { 
[objectAsking receiveData:theData withLabel:theLabel]; 
} 

Como sigo siendo un novato, me puede decir si es un buen patrón?

Gracias!

+1

No olvide liberar lo que crea, de acuerdo con las reglas de administración de memoria. http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html A partir del código que mostró, debe ser propietario y, si no se ejecuta bajo GC, eventualmente lanzar tanto 'thread' como' theData'. –

+1

Además, parece que 'getTheDataFromInternet' lo hace de forma síncrona. No hagas eso: bloquearás tu IU durante tantos milisegundos/segundos/minutos/horas/días para obtener los datos. No importa cuán pequeño sea, o cuán asombrosa sea su propia conexión a Internet: sus usuarios verán su aplicación bloquearse mientras espera la información. En su lugar, cree (y posea) un NSURLConnection para recibir de forma asíncrona: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/ Informe el progreso utilizando (al menos) un NSProgressIndicator. –

+0

Por supuesto, decidí no escribir estas líneas en aras de la claridad;) –

Respuesta

12

Su configuración es bastante correcta. Nunca desea iniciar ningún tipo de conexión de red en el hilo principal.

En su estado actual, -returnObjectToAsker se ejecutará en el hilo de fondo.

Probablemente le interese -[NSObject performSelectorOnMainThread:withObject:waitUntilDone:].

O si quería algo con Grand Central Dispatch (iOS 4, Mac OS X 10.6+), que podría hacer:

#import <dispatch/dispatch.h> 

- (void)giveMeSomeData:(id)object withLabel:(id)label { 
    dispatch_async(dispatch_get_global_queue(0,0), ^{ 
     //this runs on a background thread 
     //get data from the internet 
     dataFromTheInternet = ...; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     [object receiveData:dataFromTheInternet withLabel:label]; 
     //this runs on the main thread. Use theData 
     }); 
    }); 
} 

Desde los bloques de capturar su entorno, que ni siquiera tienen para guardar object y label en ivars. :)

+0

Gracias por su respuesta rápida :) ¿Qué prefiere, GCD o usando NSThread? –

+1

@Forchita si puedo salir con la única compatibilidad con iOS 4 u OS 10.6, entonces prefiero usar GCD porque puedo mantener toda la lógica en un solo método. –

Cuestiones relacionadas