简体   繁体   中英

Completion Block of concurrent NSOperation not being called everytime

I would like to run a concurrent NSOperation. For this reason, I have extended the NSOperation class and overridden the start and finish methods. It looks something like this:

#import "AVFrameConversionOP.h"


@implementation AVFrameConversionOP //extends NSOperation

- (void)start
{

    [self willChangeValueForKey:@"isFinished"];
    _isFinished = NO;
    [self didChangeValueForKey:@"isFinished"];

    // Begin
    [self willChangeValueForKey:@"isExecuting"];
    _isExecuting = YES;
    [self didChangeValueForKey:@"isExecuting"];

    if (_isCancelled == YES) {
        NSLog(@"** OPERATION CANCELED **");
        [self willChangeValueForKey:@"isFinished"];
        _isFinished = YES;
        [self didChangeValueForKey:@"isFinished"];
        return;
    } 

    [self performTask];
    [self finish];

}

- (void)finish
{

    [self willChangeValueForKey:@"isExecuting"];
    [self willChangeValueForKey:@"isFinished"];

    _isExecuting = NO;
    _isFinished = YES;

    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"];

    NSLog(@"operationfinished, _isFinished is %d", _isFinished);

    if (_isCancelled == YES)
    {
        NSLog(@"** OPERATION CANCELED **");
    }
}

- (void)performTask
{
    //The task is performed here
    sleep(0.1); //This is just for demonstration purposes
}
@end

I have defined the completion block for this NSOperation in the main view controller in the viewDidLoad method:

- (void)viewDidLoad {

NSLog(@"viewDidLoad!");
[super viewDidLoad];

static int counter = 0;


_frameConvOP = [[AVFrameConversionOP alloc] init]; //Initializing the modified NSOperation class
__weak typeof(self) weakSelf = self;
_frameConvOP.completionBlock = ^ {
    counter++;
    //NSLogs don't seem to work here
    /*if(counter>1){
         exit(-1); //Never happens because counter only ever becomes =1
    }*/

};
[[VideoPreviewer instance] setNSOperation:_frameConvOP]; //This is where I send the NSOperation object to the class where I'm using it

}

I'm starting the NSOperation by doing [frameConvOP start] inside of a loop. It is called continuously every time a frame is decoded, so that is to say it is called very often. I can see that the finish and start methods of the NSOperation are being called frequently through the logs. And the functions inside these methods are also being correctly called. However, the NSLogs inside the completion blocked aren't logged. I put an exit(-1) inside the completion block and the app crashed, but the NSLogs never show up. So I put a static counter in there and it only increments to 1. So the completion block is only being called once.

Can anyone explain why the completion block is being called only once? Is it because of the way I'm (incorrectly) handling the KVO for _isFinished and _isExecuting ? The completion block should be called when _isFinished is set to YES and as far as I can see, I am doing that in the finish block. And the finish block is being called quite frequently as it should be.

Any help, guidance or direction is appreciated. Please let me know if I have made any errors or if I have been less-than-clear in the post.

Thanks,

From the NSOperation class reference :

An operation object is a single-shot object—that is, it executes its task once and cannot be used to execute it again.

You are not allowed to invoke -start multiple times on a single operation object.

Another thing, in your -finish method, you need to properly nest the -willChange... and -didChange... calls. That is, you need to call -didChange... in the reverse order of the -willChange... calls:

[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];

_isExecuting = NO;
_isFinished = YES;

[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM