我有一个名为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的额外功能。有人可以帮忙吗?谢谢!
答案 0 :(得分:2)
根本问题是您已声明webServiceOperation
依赖于dbInsertOperation
(即在webServiceOperation
完成之前它不会开始dbInsertOperation
,但是你永远不会开始dbInsertOperation
,所以webServiceOperation
将永远无法运行。
如果您想dbInsertOperation
依赖于webServiceOperation
,您可能不想要:
[webServiceOperation addDependency:dbInsertOperation];
你想要:
[dbInsertOperation addDependency:webServiceOperation];
创建此依赖关系后,请务必将这些操作的两个添加到您的队列中。
[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
});