Use NSOperationQueue as a LIFO stack?

I need to make a series of URL calls (select WMS plates). I want to use the LIFO stack, so the newest URL is the most important. Now I want to display the tile on the screen, and not the fragment that was on the screen 5 seconds ago after panning.

I can create my own stack from NSMutableArray, but I wonder if NSOperationQueue can be used as a LIFO stack?

+7
source share
5 answers

Unfortunately, I think that NSOperationQueue , as the name implies, can only be used as queues, not as stacks. To avoid having to do a whole bunch of manual sorting of tasks, perhaps the easiest task is to process your queues as if they were immutable and mutated by copying. For example.

 - (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; 

It seems that currently freeing a queue that is still working (as is the case with the old operating queue) does not cause it to cancel all operations, but this is not a documented behavior, so it is probably not trustworthy. If you want to be extremely secure, key-value, observe the operationCount property in the old queue and release it when it reaches zero.

+3
source

You can prioritize operations in the operation queue using -[NSOperation setQueuePriority:] . You will have to rewrite the priorities of existing operations every time you add an operation, but you can achieve something like what you are looking for. You would significantly lower all the old ones and give the highest priority.

+4
source

I'm not sure that you are still looking for a solution, but I have the same problem several times undermined me, so I went ahead and implemented a stack of operations here: https://github.com/cbrauchli/CBOperationStack . I used it with several hundred loading operations, and it got up well.

+1
source

Unfortunately, you cannot do this without having to deal with any complex problems, because:

It is important . Before starting your operations or adding them to the operation queue, you should always configure dependencies. Dependencies added subsequently may not interfere with the launch of this operation object. (From: Concurrency Programming Guide: Configuring Interoperability Dependencies)

Take a look at this related question: The AFURLConnectionOperation 'start' method is called until it is ready and will never be called again

+1
source

Found a neat implementation of stack / LIFO functions on top of NSOperationQueue. It can be used as a category that extends NSOperationQueue or a subclass of NSOperationQueue LIFO.

https://github.com/nicklockwood/NSOperationStack

0
source

All Articles