5

我目前正在使用 GCD。但是,我听说这NSOperation实际上是一个更高级别的程序。但它要复杂得多。

在 GCD 中,在后台做一些事情只是使用我创建的这个辅助函数:

+(void)doForeGround:(void (^)())block
{
    dispatch_async(dispatch_get_main_queue(), ^{
        block();
    });
}

+(void)doBackground:(void (^)())block
{

    //DISPATCH_QUEUE_PRIORITY_HIGH
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
    //dispatch_async(dispatch_get_global_queue(-2,0), ^{
        block();
    });
}

-(void)doBackGround:(void (^)())block onComletion:(void (^)())onCompletion
{
    [BGHPTools doBackground:^{
        block();
        [BGHPTools doForeGround:^{
            onCompletion();
        }];
    }];
}

这样做NSOperation会更简单吗?

我错过了什么吗?我将如何在 NSoperation 中做同样的事情?

4

2 回答 2

6

NSOperation您可以像使用 GCD 一样做类似的事情。主要区别在于NSOperation提供了额外的功能。

例如:

  • NSOperation-cancel方法。调度队列没有取消的概念;队列中的所有块都将运行完成。
  • NSOperationQueue有一个maximumConcurrentOperationCount属性,您可以使用(例如)一次只允许运行 3 个操作。调度队列没有这样的概念;它们要么是串行的,一次只允许 1 个块,要么是并发的,libdispatch根据 CPU 使用率和可用性允许尽可能多的块。
  • AnNSOperation可以依赖于其他NSOperations,允许您推迟执行特定操作,直到其所有依赖项都运行。当相关操作等待时,其他操作将被允许在队列中“向前跳”。调度队列总是按照严格的 FIFO 顺序出队。(您可以使用 API 在一定程度上模仿依赖关系dispatch_group,但这实际上是针对不同类型的问题。)

现在,如果您不使用这些功能中的任何一个,GCD 就可以正常工作。使用 GCD 本身并没有错。只是 NSOperation 为一些额外的好特性提供了一个方便的包装器。

以下是您如何使用以下方法重写上面的示例NSOperationQueue

+(void)doForeground:(void (^)())block
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        NSLog(@"I'm running on the main thread!");
        block();
    }];
}

+(void)doBackground:(void (^)())block
{
    // Note; rather than allocating a new NSOperationQueue every time, you could
    // allocate the queue once and just refer to that queue. For simplicity, I'll
    // skip that here.
    [[NSOperationQueue new] addOperationWithBlock:^{
        NSLog(@"I'm running asynchronously on whatever thread NSOperationQueue wants!");
        block();
    }];
}

-(void)doBackground:(void (^)())block onCompletion:(void (^)())onCompletion
{
    [[NSOperationQueue new] addOperationWithBlock:^{
        block();
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            onCompletion();
        }];
    }];
}
于 2012-10-19T03:38:09.190 回答
4

用于比较的操作队列示例:

- (void)viewDidLoad
{
  // ...

  self.queue = [[NSOperationQueue alloc] init];

  // ...
}

- (void)job
{
  // background activities ...
}

- (void)startJob
{
  NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                   selector:@selector(job) 
                                                                     object:nil];
  [self.queue addOperation:op];
}
于 2012-10-19T02:34:40.303 回答