0

我有一个名为 DataFetcher 的模型类,它通过 Web 服务获取数据,然后将数据保存到 Core Data 数据存储区,然后通过委托方法更新 ViewController。这是不使用 NSOperation 的正常序列(正常工作):

NSArray *serviceQueryResult = [self queryServiceFor:@"car"];
[self setData:serviceQueryResult];
[self persistData:_data];
[_loadDelegate updateCount:_data.count]; 
[_loadDelegate receivedData:_data];

我需要将 Web 服务调用和数据库更新调用放在后台线程上。我的想法是创建一个 NSBlockOperation 来进行 Web 服务调用,然后创建另一个 NSBlockOperation 来进行数据库更新。Web 服务操作在数据库更新操作开始之前完成存在依赖性。这是我要实现的代码:

__weak DataFetcher *weakSelf = self;
__block NSArray *serviceQUeryResult;
NSBlockOperation *webServiceOperation = [NSBlockOperation blockOperationWithBlock:^{
    serviceQUeryResult = [weakSelf queryServiceFor:@"mini"];
    [weakSelf setData:serviceQUeryResult];
}];
NSBlockOperation *dbInsertOperation = [NSBlockOperation blockOperationWithBlock:^{
    [weakSelf persistData:serviceQUeryResult];
}];

[webServiceOperation addDependency:dbInsertOperation];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:webServiceOperation];

当以这种方式设置时,我的 queryServiceFor: 方法永远不会被调用。我也不确定在哪里放置两个委托方法调用,因为它们更新 UI 并且应该在主线程上。我过去曾多次使用 GCD,但现在需要 NSOperations 的一些额外功能。任何人都可以帮忙吗?谢谢!

4

1 回答 1

2

根本问题是您已声明webServiceOperation依赖于dbInsertOperation(即它不会在完成webServiceOperation之前开始dbInsertOperation),但您永远不会开始dbInsertOperation,因此webServiceOperation永远不会运行。

  1. 如果你想dbInsertOperation依赖webServiceOperation,你不想要:

    [webServiceOperation addDependency:dbInsertOperation];
    

    你反而想要:

    [dbInsertOperation addDependency:webServiceOperation];
    
  2. 创建此依赖项后,请确保将这两个操作都添加队列中。

    [queue addOperation:webServiceOperation];
    [queue addOperation:dbInsertOperation];
    

    依赖项将确保在完成dbInsertOperation之前不会开始webServiceOperation。请注意,这假定webServiceOperation同步执行其块。如果网络请求异步运行,您可能希望将其包装在它自己的并发/异步NSOperation子类中。


如果您想通过这些后台操作更新 UI,您可以:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    // update the UI here
}];

或使用 GCD,如果你想:

dispatch_async(dispatch_get_main_queue(), ^{
    // update the UI here
});
于 2014-09-26T16:55:32.193 回答