2011-02-10 17 views
17

Estoy usando addOperationWithBlock de NSOperationQueue. Desde dentro del bloque, ¿cómo verifico si debo cancelar la operación? ¿O acceder a cualquier propiedad/método de NSOperation?cómo cancelar la operación fuera de operación creada con addOperationWithBlock?

[myOperationQueue addOperationWithBlock: ^{ 

    while (/* long running loop */) 
    { 
     // how to determine here if I need to cancel? 
     // for that matter, access any NSOperation properties/methods? 

    } 

}]; 

¿Es la mejor manera de hacer esto para utilizar un NSBlockOperation?

Respuesta

49

Una mejor solución podría ser usar NSBlockOperation y agregar eso a la cola en lugar de un bloque sin formato. Se podría hacer algo como:

__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ 
    while(![operation isCancelled]){ 
    //Some long operation 
    } 
}]; 

[[self queue] addOperation:operation]; 

Esto le permite utilizar bloques mientras que le da un poco más de control sobre la operación ... y unas cuantas más NSOperation sutilezas, así (como la posibilidad de añadir bloques de terminación, por ejemplo,)

+0

eso es casi exactamente lo que quiero. pero solo funciona en ese bloque en particular. en mi caso mi bloque llama a otra función que otro bloque y en ese momento no creo que tenga acceso a 'operación'. Creo que la única forma en que mi caso funcionaría es si subligo NSOperation. – roocell

+0

pude resolver mi caso al pasar la operación a través de mis bloques. gracias. Me gusta este enfoque porque evita la subclase NSOperation. – roocell

+0

Esta solución se ve genial. La única pequeña pregunta que tengo es si la variable "operación" debe etiquetarse con "bloque". No lo creo porque no es necesario cambiar el valor de la variable dentro del bloque. – Jake

2

Realmente no puede verificar si necesita cancelar la operación si está en un bloque. Si está en un bloque y se supone que debe cancelarse, se cancela. No es posible acceder a las propiedades de NSOperation porque el bloque no es una instancia de NSOperation per se.

código Ejemplo:

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSOperationQueue *q = [[NSOperationQueue alloc] init]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:10]; 
     NSLog(@"Block 1"); 
    }]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:3]; 
     NSLog(@"Block 2"); 
    }]; 
    [q cancelAllOperations]; 
    [NSThread sleepForTimeInterval:15]; 

    [pool drain]; 
    return 0; 
} 

Si elimina las cancelAllOperations llaman entonces el fuego de bloques como era de esperar.

Sugeriría que si necesita tener un control más detallado sobre el estado de cancelación de la operación e interactuar con el NSOperationQueue sería mejor usar una NSOperation en lugar de una NSBlockOperation. Puede subclase NSOperation para lograr esto.

Cuestiones relacionadas