Chuck Doucette
Chuck Doucette

Reputation: 153

NSOperation ready but not starting on iOS 7

We created an operation framework to add some functionality not found in the base classes (e.g. tracking success/failure). Parent operations are usually non-concurrent, and may only exist to manage child operations. Child operations which are typically concurrent (downloading xml and media asynchronously).

When we run our application on iOS 7, add we a number of operations to the operation queue, ~3/4 of the operations complete, and then the app appears to hang.

When I pause the app in the debugger, and I examine the operations in the queue (sOpQueue.operations), many of them are ready to run (isReady returns TRUE), but apparently none of them are executing (isExecuting returns FALSE, and I see no evidence of any operation running on any thread).

This is a new problem as of iOS 7.

The behavior does not seem to change when I increase or decrease the number of concurrent operations.

Does anyone have any suggestions on how to determine why a ready operation is not being started?

Thanks, Chuck

Upvotes: 3

Views: 2768

Answers (2)

Rob
Rob

Reputation: 438417

Are you issuing the isReady Key Value Observing notification?

For example, I use a property:

@property (nonatomic, getter = isReady) BOOL ready;

And then have a custom setter:

- (void)setReady:(BOOL)ready
{
    [self willChangeValueForKey:@"isReady"];
    _ready = ready;
    [self didChangeValueForKey:@"isReady"];
}

As well as a custom getter that calls super:

- (BOOL)isReady
{
    return _ready && [super isReady];
}

And, because you implemented both the setter and getter, you have to manually synthesize the property at the beginning of the @implementation (usually you don't have to do this anymore, but if you implement all of the custom accessors, you have to manually @synthesize):

@synthesize ready = _ready;

Then, the operation starts when both of the following conditions are satisfied:

  • The ready property is set to YES (note, use the setter, not the ivar directly);

    self.ready = YES;
    

    or

    [self setReady:YES];
    
  • All other standard NSOperation criteria are satisfied (e.g. dependencies between operations, honoring maxConcurrentOperationCount, factoring in priorities, etc.).

Upvotes: 5

TomSwift
TomSwift

Reputation: 39502

I'll bet you have concurrent operations that haven't finished properly. Raise you number of concurrent operations and see if you can run longer before it hangs. Then figure out why your concurrent operations aren't correctly setting isFinished.

Upvotes: 2

Related Questions