2009-12-30 23 views
7

Tengo una clase. Dentro de esta clase paso una NSOperation en NSOperationQueue que vive en mis variables globales.NSOperation y NSOperationQueue callback

Ahora mi NSOperation ha finalizado. Solo quiero saber que está terminado en mi clase y que la operación pase los datos a esa clase. ¿Cómo se hace esto típicamente?

Respuesta

21

Uso el patrón de delegado: ese fue el enfoque que me recomendaron los chicos en una Conferencia de desarrolladores de Apple.

El andamio:

  1. Establecer un protocolo MyOperationDelegate con un método setResult:(MyResultObject *) result.
  2. Haga que quien necesite el resultado implemente ese protocolo.
  3. Agregue @property id<MyOperationDelegate> delegate; a la subclase NSOperation que ha creado.

El trabajo:

  1. Al crear su operación, pero antes de ponerlo en cola, se dice que debe recibir el resultado. A menudo, este es el objeto que crea la operación: [myOperation setDelegate: self];
  2. Al final de la función principal de su operación, llame al [delegate setResult: myResultObject]; para pasar el resultado.
+0

¿funcionará esto en el mismo hilo que la operación también? – Mel

+1

Sí, a menos que use performSelectorOnMainThread para especificar lo contrario. –

14

Añadir un observador para que la clase que detecta cambios en el valor de la subclase isfinished NSOperation

[operation addObserver:self 
      forKeyPath:@"isFinished" 
       options:NSKeyValueObservingOptionNew 
       context:SOME_CONTEXT]; 

luego implementar el método siguiente, que tiene que buscar el contexto de su domicilio como su oyente. Puede hacer que los datos que desea recuperar de la subclase NSOperation estén disponibles a través de un método/propiedad de acceso.

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 

Comprobar ou la KVO Programming Guide y la Concurrency Programming Guide para obtener más información.

Además, tenga en cuenta que el observador se recibirá en el mismo hilo que la Operación, por lo que puede necesitar ejecutar código en el hilo principal si desea tratar con la interfaz de usuario.

+1

encontré esta siendo problemático, debido a problemas de threads. Algunas veces el observador no es llamado. Obtuve un comportamiento errático de esta manera ... – akw

+0

¿Intentó forzar las notificaciones para disparar desde el hilo principal? – Rambatino

14

Otra alternativa ... si necesita hacer algo de trabajo cuando la operación se completa, puede envolver ese trabajo en un bloque y usar una dependencia. Esto es muy simple, especialmente con NSBlockOperation.

NSOperationQueue* myQueue = [[NSOperationQueue alloc] init]; 

NSBlockOperation* myOp = [NSBlockOperation blockOperationWithBlock:^{ 
    // Do work 
}]; 

NSBlockOperation* myOp2 = [NSBlockOperation blockOperationWithBlock:^{ 
    // Do work 
}]; 

// My Op2 will only start when myOp is complete 
[myOp2 addDependency:myOp]; 

[myQueue addOperation:myOp]; 
[myQueue addOperation:myOp2]; 

También puede utilizar setCompletionBlock

[myOp setCompletionBlock:^{ 
    NSLog(@"MyOp completed"); 
}]; 
+0

Creo que este es el enfoque más limpio, ya que puede desacoplar las operaciones muy bien, y también reutilizarlas de otra manera. –

Cuestiones relacionadas