NSOperation completion is called twice

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"]; //start the operation } } 

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.

+4
source share
1 answer

Not sure if this is the reason, but in my experience there is no need to override read-only state properties. You are responsible for checking isCancelled periodically in the main loop, and if it sets a salvation from what you are doing, but I believe that other status flags (isReady, isFinished, isExecuting) are automatically taken into account.

How many times does it fire if you cancel state flag processing and just execute your process in -main ?

EDIT: Assuming you override these flags to allow concurrency, you should read the notes in the docs

In appearance, you do not need to override isReady or isCancelled and instead override -start according to the instructions in the documents.

+4
source

Source: https://habr.com/ru/post/1479193/


All Articles