2009-10-03 20 views
6

Sto lavorando con del codice che fa un po 'di funzionamento asincrono con vari callback; Snow Leopard ha reso questo incredibilmente facile con blocchi e GCD.Quanto è leggero NSOperationQueue su Snow Leopard?

Chiamo NSTask da un NSBlockOperation in questo modo:

[self.queue addOperationWithBlock:^{ 
    NSTask *task = [NSTask new]; 
    NSPipe *newPipe = [NSPipe new]; 
    NSFileHandle *readHandle = [newPipe fileHandleForReading]; 
    NSData *inData = nil; 
    [task setLaunchPath:path]; 
    [task setArguments:arguments]; 
    [task launch]; 

    while ((inData = [readHandle availableData]) && [inData length]) { 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      // callback 
     }]; 
    } 

    [task waitUntilExit]; 
}]; 

Questo approccio funziona perfettamente. È magico, purché i miei callback gestiscano correttamente la concorrenza.

Ora, voglio essere in grado di unire alcune di queste chiamate; questo è all'interno del metodo di "aggiornamento" di un oggetto modello e potrebbe richiedere molto tempo per essere completato. Avere la sterlina dell'utente sul pulsante di aggiornamento non dovrebbe legare la macchina e tutto il resto.

Posso vedere un dilemma di implementazione qui. Posso creare un sacco di code, una per tipo di chiamata, e impostare i conteggi delle operazioni simultanee su 1 e quindi chiamare -cancelAllOperations ogni volta che è il momento di una nuova chiamata.

In alternativa, potrei fare un po 'di contabilità manuale su quali chiamate sono attualmente in corso e gestire una singola coda per oggetto modello (come sto facendo) o potrei andare ancora oltre e usare una coda globale.

Quanto pesa NSOperationQueue? La creazione di un sacco di code è una pessima decisione di architettura? C'è un modo migliore per fondere queste attività?

+2

FYI, stai perdendo il tuo NSTask e il tuo NSPipe. + nuovo equivale a + alloc/-init, il che significa che sei responsabile del rilascio di questi ... che non fai mai (nel tuo codice sopra). (a meno che, ovviamente, tu stia utilizzando GC) –

+1

È un programma solo per Snow Leopard. Spero davvero che il tuo nuovissimo codice Snow-Leopard sia raccolto dai rifiuti. :-D –

risposta

8

Se si è preoccupati per le prestazioni, non indovinare: misurare e quindi correggere eventuali colli di bottiglia che si trovano. L'aggiunta di code è semplice; provalo e guarda cosa gli strumenti ti dicono dell'effetto sulle prestazioni.

Il motivo principale per la creazione di più code è nel caso in cui si abbia qualche motivo per voler iniziare e fermarli. Se vuoi solo ottenere i vantaggi di libdispatch, puoi ottenerlo semplicemente aggiungendo operazioni alla coda principale.

0

Basta usare quante code di operazioni desiderate. Sono qui per separare parti logiche del tuo programma. Non penso che dovresti preoccuparti troppo delle prestazioni finché non stai allocando centinaia di code al secondo.

+0

Sito web? Cosa c'entra questo con i siti web? –

+0

Grazie, è ancora troppo presto la mattina. :) –

1

È possibile aggiungere più blocchi a un NSBlockOperation che verrà eseguito contemporaneamente e può essere annullato da annullando l'operazione di contenimento. Finché le tue attività individuali non devono essere serializzate, questo potrebbe funzionare.

+0

Questo non è ciò che dicono i documenti: "La classe NSBlockOperation è una sottoclasse concreta di NSOperation che gestisce l'esecuzione simultanea di uno o più blocchi." http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/NSBlockOperation_class/Reference/Reference.html –

+0

Jim, hai assolutamente ragione. Risposta aggiornata Grazie. –