I am working on a subclass of NSOperation, and I ran into this very strange problem: the completion block is called twice in a row. KVO skills seem fine, but the completion of the Block is still strangely called twice. Do I really not understand NSOperation? The documentation says that the termination block is called when isFinished becomes YES and this only happens once in my code:
- (void)main { @autoreleasepool { [self willChangeValueForKey:@"isExecuting"]; [self willChangeValueForKey:@"isReady"]; executing = YES; [self didChangeValueForKey:@"isReady"]; [self didChangeValueForKey:@"isExecuting"];
Then I just set completionBlock as follows:
self.completionBlock = ^{ NSLog(@"Completed"); }
When it ends, this method is called (it is called only ONCE, I double-checked it)
- (void)completeOperation { [self willChangeValueForKey:@"isExecuting"]; [self willChangeValueForKey:@"isFinished"]; executing = NO; completed = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; }
But the final block is called twice and prints โCompletedโ in the console twice.
And here are the methods that indicate the current state:
- (BOOL)isReady { if (executing || cancelled || completed) { return NO; } return YES; } - (BOOL)isCancelled { return cancelled; } - (BOOL)isConcurrent { return YES; } - (BOOL)isExecuting { return executing; } - (BOOL)isFinished { return completed; }
isCancelled never accesses YES in my test code, so it cannot be the reason for this.
I really don't understand why callBlock is called twice. Even when the completion block is set to zero from the completion block, it is sometimes called twice, which is even more strange.
source share