2009-04-18 7 views
9

Tengo una NSInvocationOperation que descargaría y analizaría una serie de NSXMLDocuments en segundo plano a mi interfaz de usuario sensible.¿Cómo detener una NSInvocationOperation?

Mi intento de detener la operación de Invocación es llamar a mi NSOperationQueue's cancellAllOperations. Pero parece que esto no detendrá la ejecución de la invocación.

¿Alguna idea sobre cómo abordar este problema?

Respuesta

3

Todo depende de la ejecución de su objeto NSOperation para realmente parada lo que está haciendo, limpiar, y la salida cuando se recibe una notificación de que ha sido cancelada. La mensajería en la que desea cancelar todas las operaciones en la cola hará que la cola deje de arrastrar las nuevas operaciones para que se ejecute y enviará el mensaje cancelar a cualquier operación que se esté ejecutando.

En el método principal de su operación, debe comprobar isCancelled y manejar ese estado cuando en realidad se cancela.

Para obtener más información, consulte Creating and Managing Operation Objects en la Guía de programación de subprocesos.

+0

Pero vea las otras respuestas, parece que no puede hacer esto (al menos en la forma estándar de comprobar 'isCancelled') cuando se usa' NSInvocationOperation'. – jrdioko

5

La publicación anterior es excelente, pero para responder más directamente a la pregunta original: parece que no puede detener el objeto NSInvocationOperation porque no admite cancelaciones. Tendrás que subclasificarlo.

11

ACTUALIZACIÓN: Los instrumentos muestran goteos cuando hago esto. ¡Proceda con precaución! Estoy guardando esto aquí en caso de que realmente estoy en algo y alguien más puede encontrar la manera de superar el obstáculo de la fuga.

Aquí es una idea retorcida, que estoy volver a intentar mientras escribo esto:

Establecer la operación como el objeto para NSInvocationOperation 's initWithTarget: Selector: Objeto: método. Suponiendo que ya tiene un NSOperationQueue (lo llamaremos cola):

NSInvocationOperation *operation = [NSInvocationOperation alloc]; 
operation = [operation initWithTarget:self selector:@selector(myOperation:) object:operation]; 
[queue addOperation:operation]; 
[operation release]; 

Tenga en cuenta que tenemos que romper el alloc en su propia llamada. De lo contrario, no podemos configurar objeto en operación!

Luego, dentro de su método de operación, eche el objeto hacia atrás y espolvoree las verificaciones para se cancela según lo desee. Por ejemplo:

- (void)myOperation:(id)object { 
    NSInvocationOperation *operation = (NSInvocationOperation *)object; 
    if ([operation isCancelled]) return; 
    ... 
    } 

Asegúrese de que el selector termina con dos puntos de vuelta en el initWithTarget: ... llamada, ya que vas a estar pasando en un objeto ahora.

Hasta ahora, todo bien. Ahora si puedo forzar cancelAllOperations, sabré si esto realmente funciona. :)

+0

No lo intentaré debido a fugas. ¡Pero la idea es genial! –

8

Debes comprobar que NSInvocationOperation isCancelled es YES. hacer eso en NSInvocationOperation, puede utilizar Clave Valor Observación:

Añadir su objeto como NSInvocationOperation isCancelled observador cuando se ejecuta la operación:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:<targetObj> selector:@selector(<targetMethod>) object:nil]; 
[operation addObserver:<targetObj> forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil]; 
[operQueue addOperation:operation]; 
[operation release]; 

Luego, en targetObj implemento

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

para ver para que isCancelled sea cambiado por cancellAllOperations de NSOperationQueue. Puede establecer un indicador privado aquí y targetMethod puede verificarlo y cancelarlo si es necesario.