2016-08-10 22 views
1
- (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]; 
} 

第一件事主要在基类中不自然地被设置完毕没有和执行为yes:把NSOperation主要变成超级可以接受吗?

- (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]; 
} 

因为它不是一个抽象的,将在其自身的使用。

循环是调试/看门狗仅供参考

在正常操作它没有跳闸操作完成 如果这个回调:

- (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]; 
} 

被调用时“processImage来:”将完成(及时)。

非常基类是

@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 

回答

1

您当然可以(并且我们经常这样做)继承自己的具体NSOperation子类。

要使基类具有可分类性,您需要确保只执行一次self.executing = true。现在,基类和子类中的main都这样做了,因此你会做两次。典型的解决方案是将它从这两个main实现中拉出来,并在基类的start中执行。无论如何,苹果建议你在start这个东西。

因此已经从两个main实现去除self.finishedself.executing的东西,你就可以实现start

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

    self.executing = YES; 

    [self main]; 
} 

注意,你不必叫self.finished = false当操作开始,因为这将发送不必要的KVO。


一个无关的观察:

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

就个人而言,根据processImage的设计,我可能会倾向于完全消除while循环。你通常希望避免这样的投票。例如,我可能会将[self done]置于适当的委托方法中,然后设置一个计时器或dispatch_after来进行超时。

- (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 
     } 
    }); 
} 
+0

是的,派生类是同步的。基地不是。更新了显示整个基类主 –

+0

的问题坦率地说,扩展基类的“主”会引发更多问题。看到我修改后的答案。问题是这个基类是否实现了'isAsynchronous'(或'isConcurrent')或者不是(如果你这样做了,它是否返回true或false)? – Rob

+0

它返回YES。而且这样做是因为while循环最终只能在调试版本中生成,所以如果有任何意外(冗长)的处理,我会在发货之前收到警报。让我进一步更新问题。秒。 –