Why is my NSOperation subclass never finishing?

cocoa-touch, key-value-observing, nsoperation

Solution

It looks like whatever KVO notifications `@synthesize` sends aren't enough for `NSOperationQueue` to move on.

Sending the notifications manually fixes the problem:

- (void)start
{
    @autoreleasepool {
        [self willChangeValueForKey:@"isExecuting"];
        self.isExecuting = YES;
        [self didChangeValueForKey:@"isExecuting"];

        NSURLRequest *URLRequest = [self buildRequest];
        if (!URLRequest) {
            [self willChangeValueForKey:@"isFinished"];
            [self willChangeValueForKey:@"isExecuting"];
            _isExecuting = NO;
            _isFinished = YES;
            [self didChangeValueForKey:@"isExecuting"];
            [self didChangeValueForKey:@"isFinished"];
            return;
        }

        self.HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest];

        _HTTPOperation.completionBlock = [^{
            [self completed];

            [self willChangeValueForKey:@"isFinished"];
            [self willChangeValueForKey:@"isExecuting"];
            _isExecuting = NO;
            _isFinished = YES;
            [self didChangeValueForKey:@"isExecuting"];
            [self didChangeValueForKey:@"isFinished"];
        } copy];

        [_HTTPOperation start];
    }
}

See also:

- Why does NSOperation disable automatic key-value observing?

Problem

I have an `NSOperation` subclass that I want to run concurrently. My understanding is that for concurrent operations to work: - I need to define `isConcurrent` to return `YES`. - I need to define the `start` method - I need to send KVOs notification for `isExecuting` and `isFinished` when it's done. - Using `@synthesize` will automatically send the appropriate KVO notifications when the values for `isExecuting` and `isFinished` are changed. Despite this, I have verified that my queue never moves on to the next item. Here's the meat of my code: ``` @interface MyOperation() @property (readwrite) BOOL isExecuting; @property (readwrite) BOOL isFinished; @end @implementation MyOperation - (void)start { @autoreleasepool { self.isExecuting = YES; self.HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest]; _HTTPOperation.completionBlock = [^{ [self completed]; self.isExecuting = NO; self.isFinished = YES; } copy]; [_HTTPOperation start]; } } - (BOOL)isConcurrent { return YES; } - (void)completed { } @end ``` What am I missing? (This is on an iPhone, but I can't imagine that matters.)

Original source

Related problems