2016-08-10 44 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循環最終只能在調試版本中生成,所以如果有任何意外(冗長)的處理,我會在發貨之前收到警報。讓我進一步更新問題。秒。 –