[英]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的finish
和start
方法经常通过日志被调用。 这些方法中的函数也被正确调用。 但是,不会记录完成中的NSLogs。 我在完成块中放入了一个exit(-1),应用程序崩溃了,但NSLogs却从未显示出来。 因此,我在其中放置了一个静态计数器,它仅增加到1。因此,完成块仅被调用一次。
谁能解释为什么仅一次调用完成块? 是因为我(错误地)处理_isFinished
和_isExecuting
的KVO的_isExecuting
吗? 当_isFinished
设置为YES时,应该调用完成块,据我所知,我是在完成块中这样做的。 而且,finish块应该经常被调用。
任何帮助,指导或指示,我们感激不尽。 如果我有任何错误,或者帖子中的内容不够清楚,请告诉我。
谢谢,
操作对象是单发对象,即,它只执行一次任务,而不能再次用于执行它。
您不允许在单个操作对象上多次调用-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.