2009-12-30 14 views
7

Ho una classe. All'interno di questa classe passo una NSOperation in NSOperationQueue che vive nelle mie variabili globali.NSOperation e NSOperationQueue callback

Ora la mia NSOperformance è terminata. Voglio solo sapere che è finito nella mia classe e che l'operazione passa i dati a quella classe. Come è fatto in genere?

risposta

21

Uso lo schema del delegato: questo è stato l'approccio consigliato a me dai ragazzi in una conferenza degli sviluppatori Apple.

Il ponteggio:

  1. Impostare un protocollo MyOperationDelegate con un metodo setResult:(MyResultObject *) result.
  2. Chiunque abbia bisogno del risultato implementa tale protocollo.
  3. Aggiungi @property id<MyOperationDelegate> delegate; alla sottoclasse NSOperation che hai creato.

Il lavoro:

  1. Quando si crea l'operazione, ma prima di coda che, dici che chi deve ricevere il risultato. Spesso, questo è l'oggetto che crea l'operazione: [myOperation setDelegate: self];
  2. Alla fine della funzione principale dell'operazione, chiamare [delegate setResult: myResultObject]; per passare il risultato.
+0

verrà eseguito sullo stesso thread dell'operazione? – Mel

+1

Sì, a meno che non si usi performSelectorOnMainThread per specificare altrimenti. –

14

Aggiungi un osservatore a voi classe che ascolto per le modifiche al valore di isfinished della sottoclasse NSOperation

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

quindi implementare il seguente metodo, avendo lo sguardo per il contesto vostro registrato come il vostro ascoltatore. È possibile rendere i dati che si desidera recuperare dalla sottoclasse NSOperation disponibile tramite un metodo/proprietà accessor.

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

Controllare ou la KVO Programming Guide e la Concurrency Programming Guide per maggiori informazioni.

Inoltre, si noti che l'osservatore verrà ricevuto sullo stesso thread dell'operazione, quindi potrebbe essere necessario eseguire il codice sul thread principale se si desidera gestire l'interfaccia utente.

+1

Ho trovato questo essere problematica, a causa di problemi di threading. A volte l'osservatore non viene chiamato. Ho avuto un comportamento erratico in questo modo ... – akw

+0

Hai provato a forzare le notifiche a sparare dal thread principale? – Rambatino

14

Un'altra alternativa ... se hai bisogno di lavorare un po 'quando l'operazione è completa, puoi avvolgere quel lavoro in un blocco e usare una dipendenza. Questo è molto semplice, specialmente 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]; 

Inoltre è possibile utilizzare setCompletionBlock

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

Credo che questo sia l'approccio più pulito, in quanto è possibile disaccoppiare le operazioni in modo corretto e anche riutilizzarle in altro modo. –

Problemi correlati