我想运行一个并发的NSOperation。出于这个原因,我扩展了NSOperation类并重写了开始和结束方法。它看起来像这样:
#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。每次解码帧时都会连续调用它,这就是说它经常被调用。我可以看到NSOperation的finish
和start
方法经常通过日志调用。并且这些方法中的函数也被正确调用。但是,完成阻止内的NSLogs未被记录。我在完成块中放置了一个exit(-1),应用程序崩溃了,但NSLogs从未出现过。所以我在那里放了一个静态计数器,它只增加到1.所以完成块只被调用一次。
有人可以解释为什么只调用一次完成块吗?是因为我(错误地)处理_isFinished
和_isExecuting
的KVO的方式?当_isFinished
设置为YES时应该调用完成块,据我所知,我在完成块中执行此操作。并且应该非常频繁地调用终点块。
感谢任何帮助,指导或指示。如果我有任何错误或者我在帖子中不太清楚,请告诉我。
谢谢,
答案 0 :(得分:0)
来自NSOperation
class reference:
操作对象是单击对象 - 也就是说,它执行一次任务,不能再用来执行它。
不允许您在单个操作对象上多次调用-start
。
另一方面,在-finish
方法中,您需要正确嵌套-willChange...
和-didChange...
来电。也就是说,您需要按-didChange...
来电的相反顺序呼叫-willChange...
:
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];