2016-08-10 3 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]; 
} 

первая вещь, главный в базовом классе не делает, естественно, установка закончена к нет и исполнения в да:Допустимо ли маргаритка NSOperation 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]; 
} 

потому что это не абстрактное и будет использоваться самостоятельно, а также.

петля для целей отладки/сторожевых только

в нормальном режиме она не сработала операция выполняется , если этот обратный вызов:

- (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 базового класса. Apple предлагает, чтобы вы делали это в start, во всяком случае.

Таким образом, устранив вещи self.finished и self.executing с обеих main реализаций, вы можете реализовать start:

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

    self.executing = YES; 

    [self main]; 
} 

Обратите внимание, вы не должны вызывать self.finished = false, когда операция начинается, потому что будет посылать ненужный КВО.


неродственное наблюдение:

Если вы держите петлю 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 может оказаться в отладочных сборках только для того, чтобы при любой неожиданной (длительной) обработке я буду предупрежден до того, как это будет отправлено. Позвольте мне еще раз уточнить вопрос. Sec. –

Смежные вопросы