2011-02-10 6 views
17

Sto usando addOperationWithBlock di NSOperationQueue. Da dentro il blocco, come faccio a verificare se dovrei annullare l'operazione? O accedere a qualsiasi proprietà/metodi di NSOperation?come annullare l'operazione creata 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? 

    } 

}]; 

È il modo migliore per eseguire questa operazione per utilizzare NSBlockOperation?

risposta

49

Una soluzione migliore potrebbe essere quella di utilizzare NSBlockOperation e aggiungerla alla coda anziché a un blocco raw. Si potrebbe fare qualcosa di simile:

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

[[self queue] addOperation:operation]; 

Ciò consente di utilizzare i blocchi mentre si dà un po 'più di controllo sul funzionamento ... e qualche altro NSOperation sottigliezze così (come la possibilità di aggiungere blocchi di completamento, per esempio).

+0

questo è quasi esattamente quello che voglio. ma funziona solo in quel particolare blocco. nel mio caso il mio blocco chiama un'altra funzione che è un altro blocco e, a quel punto, non penso più di avere accesso a "operazione". Penso che l'unico modo in cui il mio caso possa funzionare è quello di sublocare NSOperation. – roocell

+0

sono stato in grado di risolvere il mio caso passando l'operazione attraverso i miei blocchi. grazie - mi piace questo approccio perché evita sottoclassi NSOperation. – roocell

+0

Questa soluzione sembra fantastica. L'unica piccola domanda che ho è, la variabile 'operazione' deve essere taggata con __block? Non penso perché il valore della variabile non debba essere modificato all'interno del blocco. – Jake

2

Non è possibile verificare realmente se è necessario annullare l'operazione se si trova in un blocco. Se è in un blocco e deve essere cancellato, viene cancellato. L'accesso alle proprietà NSOperation non è possibile perché il blocco non è un'istanza NSOperation di per sé.

codice Esempio:

#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; 
} 

Se si rimuovono le cancelAllOperations chiamano poi il fuoco blocchi come ci si aspetterebbe.

Suggerirei che se è necessario avere un controllo più granulare sullo stato di annullamento dell'operazione e interagire con NSOperationQueue, sarebbe meglio utilizzare NSOperation anziché NSBlockOperation. È possibile sottoclasse NSOperation per ottenere ciò.