簡體   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