2012-04-09 12 views
7

ho bisogno di fare una serie di chiamate url (recupero di tessere WMS). Voglio utilizzare uno stack LIFO in modo che la più recente chiamata url sia la più importante. Voglio visualizzare la tessera sullo schermo ora, non una tessera che era sullo schermo 5 secondi fa, dopo una panoramica.usa NSOperationQueue come stack LIFO?

posso creare il mio stack da un NSMutableArray, ma mi chiedo se un NSOperationQueue può essere utilizzato come stack LIFO?

risposta

3

Tristemente penso che gli NSOperationQueue s siano, come suggerisce il nome, utilizzabili solo come code - non come pile. Per evitare di dover eseguire un intero gruppo di marshalling manuale delle attività, probabilmente la cosa più semplice è trattare le code come se fossero immutabili e mutare copiando. Per esempio.

- (NSOperationQueue *)addOperation:(NSOperation *)operation toHeadOfQueue:(NSOperationQueue *)queue 
{ 
    // suspending a queue prevents it from issuing new operations; it doesn't 
    // pause any already ongoing operations. So we do this to prevent a race 
    // condition as we copy operations from the queue 
    queue.suspended = YES; 

    // create a new queue 
    NSOperationQueue *mutatedQueue = [[NSOperationQueue alloc] init]; 

    // add the new operation at the head 
    [mutatedQueue addOperation:operation]; 

    // copy in all the preexisting operations that haven't yet started 
    for(NSOperation *operation in [queue operations]) 
    { 
     if(!operation.isExecuting) 
      [mutatedQueue addOperation:operation]; 
    } 

    // the caller should now ensure the original queue is disposed of... 
} 

/* ... elsewhere ... */ 

NSOperationQueue *newQueue = [self addOperation:newOperation toHeadOfQueue:operationQueue]; 
[operationQueue release]; 
operationQueue = newQueue; 

Sembra al momento che il rilascio di una coda che sta ancora lavorando (come accadrà alla vecchia coda di operazione) non causa per annullare tutte le operazioni, ma che non è documentato comportamento in modo probabilmente non degno di fiducia. Se si desidera essere veramente sicuri, il valore-chiave osserva la proprietà operationCount nella vecchia coda e la rilascia quando va a zero.

+0

I belive questo dovrebbe funzionare, ho deciso di creare solo il mio proprio stack da un NSMutableArray. Grazie per l'input. – Padin215

+0

Per la cronaca, avrei evitato di creare il mio stack personale perché sei quindi responsabile dell'emissione di operazioni e del monitoraggio dei loro progressi, cioè finisci per reimplementare molte delle funzioni di 'NSOperationQueue'. Se stessimo usando operazioni simultanee, avreste praticamente finito per essere meno efficienti. Ovviamente niente di tutto ciò è rilevante per le tue esigenze specifiche e sono sicuro che stai facendo la cosa giusta, ho solo pensato di dirlo per completezza. – Tommy

+0

sto creando una serie di URL che ho bisogno di chiamare per una tessera WMS. controllo se ho X tile, se non è in una cache, ho messo l'URL in pila. Ho un timer che spara sempre 2 secondi che creerà la richiesta e metterlo in una coda GDC da eseguire. – Padin215

4

È possibile impostare la priorità delle operazioni in una coda di operazioni utilizzando -[NSOperation setQueuePriority:]. Dovrai ridefinire le priorità delle operazioni esistenti ogni volta che aggiungi un'operazione, ma puoi ottenere qualcosa di simile a quello che stai cercando. In pratica, dovresti abbassare di livello tutti i vecchi e dare la più recente priorità assoluta.

+0

Per citare dalla documentazione Apple: È necessario utilizzare i valori di priorità solo se necessario per classificare la priorità relativa delle operazioni non dipendenti. I valori di priorità non devono essere utilizzati per implementare la gestione delle dipendenze tra diversi oggetti operativi. Trovato qui: http://stackoverflow.com/questions/20297333/function-setqueuepriority-has-different-performance-on-ios-emulator-and-on-iphon. Cercando di impostare l'ordine con setQueuePriority finito con l'esecuzione casuale –

+0

@MichalGumny, la citazione del documento Apple convalida il mio suggerimento. Stiamo cercando di "classificare la priorità relativa delle operazioni non dipendenti". Non stiamo cercando di implementare la gestione delle dipendenze. La coda, se non sospesa, può avviare un'operazione non appena viene aggiunta o ogni volta che si trova al di sotto del limite massimo. concorrenza. Se l'altra domanda che hai citato avesse sospeso la coda, avrebbe funzionato bene. La coda può iniziare le operazioni in qualsiasi momento e, ovviamente, la modifica della priorità delle operazioni non cambierà ciò che è già accaduto. Ma la priorità viene rispettata quando viene avviata una nuova operazione. –

+0

La domanda era per ordine LIFO, Apple ha scritto "priorità relativa" che penso suggerisca che non possiamo essere sicuri al 100% che la priorità oder sarà preservata. Ho persino scritto un piccolo codice per controllarlo e l'ordine non è esattamente come supposto: http://pastebin.com/ZM8G9s2P. Ofc Posso sbagliarmi, correggimi se questo è il caso –

1

Non sono sicuro che tu stia ancora cercando una soluzione, ma ho lo stesso problema che mi ha infastidito per un po ', quindi sono andato avanti e ho implementato uno stack operativo qui: https://github.com/cbrauchli/CBOperationStack. L'ho usato con poche centinaia di operazioni di download e ha retto bene.

1

Purtroppo, non è possibile farlo senza incorrere in alcuni problemi difficili, perché:

Importante Si dovrebbe sempre configurare le dipendenze prima di eseguire le operazioni o aggiungendoli a una coda di funzionamento. Le dipendenze aggiunte in seguito potrebbero non impedire l'esecuzione di un dato oggetto operazione. (Da: Concurrency Programming Guide: Configuring Interoperation Dependencies)

Date un'occhiata a questa domanda correlata: AFURLConnectionOperation 'start' method gets called before it is ready and never gets called again afterwards

0

Trovato un'implementazione pulita dello stack/LIFO presenta sulla parte superiore del NSOperationQueue. Può essere utilizzato come categoria che estende NSOperationQueue o una sottoclasse LIFO NSOperationQueue.

https://github.com/nicklockwood/NSOperationStack

+0

Purtroppo non è possibile farlo senza incorrere in problemi delicati: http://stackoverflow.com/questions/14821406/afurlconnectionoperation-start-method-gets-called-before-it-is-ready-and-never –

Problemi correlati