哪一个更容易使用? GCD还是NSOperation?

时间:2012-10-19 02:24:11

标签: objective-c xcode4.5 grand-central-dispatch nsoperation

我目前正在使用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上做同样的事情?

2 个答案:

答案 0 :(得分:6)

您可以使用NSOperation执行与GCD相同的操作。主要区别在于NSOperation提供了额外的功能。

例如:

  • NSOperation-cancel方法。派遣队列没有取消的概念;队列中排队的所有块都将运行完毕。
  • NSOperationQueue具有maximumConcurrentOperationCount属性,您可以使用(例如)仅允许一次运行3个操作。派遣队列没有这样的概念;它们是串行的,一次只允许1个块,或者并发,允许libdispatch根据CPU使用率和可用性认为可行。{/ li>
  • NSOperation可以依赖于其他NSOperation,允许您推迟执行特定操作,直到其所有依赖项都已运行。在依赖操作等待时,将允许其他操作在队列中“跳转”。调度队列始终以严格的FIFO顺序出列。 (您可以使用dispatch_group API模仿依赖关系,但这确实是针对不同类型的问题。)

现在,如果你没有使用任何这些功能,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();
        }];
    }];
}

答案 1 :(得分: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];
}