繁体   English   中英

并非每次都调用并发NSOperation的完成块

[英]Completion Block of concurrent NSOperation not being called everytime

我想运行一个并发的NSOperation。 因此,我扩展了NSOperation类并覆盖了start和finish方法。 看起来像这样:

#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

我已经在viewDidLoad方法的主视图控制器中为此NSOperation定义了完成块:

- (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

}

我通过在循环内执行[frameConvOP start] 每次解码帧时都会连续调用它,也就是说,它经常被调用。 我可以看到NSOperation的finishstart方法经常通过日志被调用。 这些方法中的函数也被正确调用。 但是,不会记录完成中的NSLogs。 我在完成块中放入了一个exit(-1),应用程序崩溃了,但NSLogs却从未显示出来。 因此,我在其中放置了一个静态计数器,它仅增加到1。因此,完成块仅被调用一次。

谁能解释为什么仅一次调用完成块? 是因为我(错误地)处理_isFinished_isExecuting的KVO的_isExecuting吗? _isFinished设置为YES时,应该调用完成块,据我所知,我是在完成块中这样做的。 而且,finish块应该经常被调用。

任何帮助,指导或指示,我们感激不尽。 如果我有任何错误,或者帖子中的内容不够清楚,请告诉我。

谢谢,

NSOperation类参考

操作对象是单发对象,即,它只执行一次任务,而不能再次用于执行它。

您不允许在单个操作对象上多次调用-start

另一件事,在您的-finish方法中,您需要正确地嵌套-willChange...-didChange...调用。 也就是说,你需要调用-didChange...在相反的顺序-willChange...电话:

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

_isExecuting = NO;
_isFinished = YES;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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