首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >雏菊NSOperation main变成超级可以接受吗?

雏菊NSOperation main变成超级可以接受吗?
EN

Stack Overflow用户
提问于 2016-08-10 09:32:48
回答 1查看 105关注 0票数 2
代码语言:javascript
复制
- (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];
}

基类中的首要任务自然是将finished设置为no,然后将执行设置为yes:

代码语言:javascript
复制
- (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];
}

因为它不是抽象的,也会单独使用。

该循环仅用于调试/监视狗。

在正常操作中,如果此回调:

代码语言:javascript
复制
- (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:“完成时(以及时的方式)调用。

基类是

代码语言:javascript
复制
@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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-10 09:40:16

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

要使基类子类可以使用,您需要确保只执行一次self.executing = true。现在,基类和子类中的main都执行此操作,因此您将执行两次。典型的解决方案是将其从这两个main实现中提取出来,并在基类的start中执行。无论如何,苹果建议你在start上做这件事。

因此,在从两个self.finished实现中删除了self.executingself.executing之后,您就可以实现start了。

代码语言:javascript
复制
- (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

代码语言:javascript
复制
- (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
        }
    });
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38869486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档