Search code examples
iosnsoperationnsoperationqueuefifo

Using dependencies to create a FIFO NSOperationQueue


I've created a NSOperationQueue subclass, set maxConcurrentOperations to 1, and have overridden the addOperation method to be the following:

-(void)addOperation:(NSOperation *)op
{
    // If there are already operations on the queue, add the last operation as a dependency to the delay. Ensures FIFO.
    if ([[self operations] count] > 0) [op addDependency:[self.operations lastObject]];
    [super addOperation:op];
}

This was suggested here somewhere (I don't have the link at hand). The trouble is that I occasionally get a crash here:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

At crash time, [[self operations] count] == 0, so presumably in the nanoseconds between the check [[self operations] count] > 0, and the addDependency call, the last operation on the queue finished executing, and became nil.

My question is, how do I work around this?


Solution

  • To avoid this NSInvalidArgumentException issue, just establish a local reference to the lastObject for the duration of this method and then test that:

    NSOperation *lastOperation = [self.operations lastObject];
    if (lastOperation) [op addDependency:lastOperation];