Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将主操作转换为超级操作是否可以接受?_Ios_Nsoperation - Fatal编程技术网

Ios 将主操作转换为超级操作是否可以接受?

Ios 将主操作转换为超级操作是否可以接受?,ios,nsoperation,Ios,Nsoperation,基类中main自然要做的第一件事是将finished设置为no,并将executing设置为yes: - (void)main { IDBAssert0(self.bestCapture.webpCandidate); self.finished = NO; self.executing = YES; NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; UIImage *possiblycorrupted = [UIIma

基类中main自然要做的第一件事是将finished设置为no,并将executing设置为yes:

- (void)main
{
IDBAssert0(self.bestCapture.webpCandidate);
self.finished = NO;
self.executing = YES;

NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
UIImage *possiblycorrupted = [UIImage imageWithWebPData:self.bestCapture.webpCandidate];
NSTimeInterval  webpInterval = [NSDate timeIntervalSinceReferenceDate]-now;
NSDLog(@"it tooke %.2f sec to unpack webp", webpInterval);

self.microblinkCandidate = possiblycorrupted; // data superclass nsoperation processes

[super main];
}
因为它不是一个抽象的,也将被单独使用

循环仅用于调试/监视目的

在正常操作中,它不会跳闸,操作完成 如果此回调:

- (void)main
{
self.finished = NO;
self.executing = YES;
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
start = now;

CGSize size = [self.microblinkCandidate size];
IDBAssert0(size.width && size.height);
IDBAssert0(self.microblink);
// this starts async processing
[self.microblink processImage:self.microblinkCandidate
           scanningRegion:CGRectMake(0.0, 0.0, 1.0, 1.0)
                 delegate:self];

while (![self isCancelled])
{
    sleep(1);
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    if(now - start > 5) {
        // #5677 microblink watchdog to detect hangs
        [self cancel];
        break;
    }

}
[self done];
}
-(无效)扫描视图控制器:(UIViewController*)扫描视图控制器
DID输出结果:(NSArray*)结果
{
如果([结果计数]>0){
NSTimeInterval now=[NSDate timeIntervalSinceReferenceDate];
NSDLog(@“在%.1fs中找到条形码”,现在-开始);
self.microblinkSuccessHandler();
}否则{
IDBASERT0(self.microblinkFailureHandler);
self.microblinkFailureHandler();
}
[自行完成];
}
当“processImage:”将完成(及时)时调用

最基本的类是

- (void)scanningViewController:       (UIViewController<PPScanningViewController>*)scanningViewController
          didOutputResults:(NSArray*)results
{
if([results count]>0) {
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    NSDLog(@"found barcode in %.1fs", now - start);
    self.microblinkSuccessHandler();
}else{
    IDBAssert0(self.microblinkFailureHandler);
    self.microblinkFailureHandler();
}
[self done];
}
@实现IDBSynchronousOperation
@综合执行=_执行;
@合成完成=_完成;
-(BOOL)完成了
{
返回已完成;
}
-(void)setFinished:(BOOL)finished
{
[self-willChangeValueForKey:@“isFinished”];
_完成=完成;
[self-didChangeValueForKey:@“isFinished”];
}
-(BOOL)执行
{
返回执行;
}
-(void)setExecuting:(BOOL)executing
{
[self Will ChangeValueForkey:@“isExecuting”];
_执行=执行;
[self-didChangeValueForKey:@“正在执行”];
}
-(instancetype)初始化
{
self=[super init];
如果(自我){
//self.completionBlock=^{
//NSDLog(@“图像条码搜索已完成”);
//      };
IDBASERT0(sizeof(_executing)您当然可以(而且我们经常这样做)为您自己的具体
NSOperation
子类创建子类

要使基类成为子类,您需要确保只执行一次
self.executing=true
。现在,基类和子类中的
main
都执行它,因此您将执行两次。典型的解决方案是将它从这两个
main
实现中拉出,然后在中执行<基本类的code>start
。无论如何,苹果建议您在
start
中执行此操作

因此,从两个
main
实现中删除了
self.finished
self.executing
内容后,您就可以实现
start

@implementation IDBAsynchronousOperation

@synthesize executing = _executing;
@synthesize finished = _finished;

-(BOOL)isFinished
{
return _finished;
}

- (void)setFinished:(BOOL)finished
{
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}

-(BOOL)isExecuting
{
return _executing;
}

- (void)setExecuting:(BOOL)executing
{
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}

- (instancetype)init
{
self = [super init];
if (self) {
    //      self.completionBlock = ^{
    //          NSDLog(@"image barcode search has finished");
    //      };
    IDBAssert0(sizeof(_executing)<2);
}
return self;
}

-(BOOL)isAsynchronous
{
return YES;
}

@end
注意,当操作开始时,您不必调用
self.finished=false
,因为这将发送不必要的KVO


无关的观察:

如果在基类中保留
while
循环,我建议在
[self isCancelled]
或调用了
processImage
委托完成方法时退出循环(也许可以更新一些状态属性以指定何时调用该委托方法)。现在,如果
processImage
在超时之前完成,它将使操作运行整整5秒钟

就个人而言,取决于
processImage
的设计方式,我可能倾向于完全删除
循环。您通常希望完全避免这样的轮询。例如,我可能会将
[自行完成]
在适当的委托方法中,然后为超时设置计时器或
调度\u

- (void)start {
    if ([self isCancelled]) {
        self.finished = YES;
        return;
    }

    self.executing = YES;

    [self main];
}

是的,派生类是同步的。基类不是。更新了显示整个基类的问题。坦率地说,扩展的基类的
main
引发了更多的问题。请参阅我的修订答案。问题是这个基类是否实现了
isasacronous
(或
isConcurrent
)(如果您这样做了,它会返回
true
还是
false
)?它会返回YES。这样做是因为while循环可能只会在调试版本中结束,以便在出现任何意外(冗长)时处理在发货前会通知我。让我进一步更新问题。第二节用您认为相关的部分更新了问题,并相应更新了我的答案。
- (void)main {
    NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
    start = now;

    CGSize size = [self.microblinkCandidate size];
    IDBAssert0(size.width && size.height);
    IDBAssert0(self.microblink);

    // this starts async processing

    [self.microblink processImage:self.microblinkCandidate
                   scanningRegion:CGRectMake(0.0, 0.0, 1.0, 1.0)
                         delegate:self];

    // cancel upon timeout

    typeof(self) __weak weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        typeof(self) __strong strongSelf = weakSelf;
        if ([strongSelf isExecuting]) {
            [strongSelf cancel];
            [strongSelf done];   // if canceling calls the delegate method that calls `done`, then you don't need this here
        }
    });
}