当两个单独的NSFetchRequests都完成时采取行动
我正在使用具有核心数据的远程数据库,当执行以下提取请求(取决于Internet连接)时,可能需要一些时间。 我想监视这两个请求,当它们完成时 – 无论成功还是失败 – 我想引发另一种方法。
FetchRequest 1:
[self.managedObjectContext executeFetchRequest:fetchRequest1 onSuccess:^(NSArray *results) { //Succcess [self.refreshControl endRefreshing]; } onFailure:^(NSError *error) { [self.refreshControl endRefreshing]; }];
FetchRequest 2:
[self.managedObjectContext executeFetchRequest:fetchRequest2 onSuccess:^(NSArray *results) { //Succcess [self.refreshControl endRefreshing]; } onFailure:^(NSError *error) { [self.refreshControl endRefreshing]; }];
我想等到提取请求1和2都完成后再调用另一个方法。
我可以使用NSOperationQueue
来监视这两个块吗? 如果不是的话,最好的方法是什么时候两个街区都已经完工?
当你有依赖的asynchronous任务时,你有两个select:
-
代码更改最less的最简单的解决scheme是使用信号量:
// create a semaphore dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); // initiate two requests (signaling when done) [self.managedObjectContext executeFetchRequest:fetchRequest1 onSuccess:^(NSArray *results) { [self.refreshControl endRefreshing]; dispatch_semaphore_signal(semaphore); } onFailure:^(NSError *error) { [self.refreshControl endRefreshing]; dispatch_semaphore_signal(semaphore); }]; [self.managedObjectContext executeFetchRequest:fetchRequest2 onSuccess:^(NSArray *results) { [self.refreshControl endRefreshing]; dispatch_semaphore_signal(semaphore); } onFailure:^(NSError *error) { [self.refreshControl endRefreshing]; dispatch_semaphore_signal(semaphore); }]; // now create task to to wait for these two to finish signal the semaphore dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // wait for the two signals from the two fetches to be sent dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // now do whatever you want when those two requests finish // if you need to do any UI update or do any synchronizing with the main queue, just dispatch this to the main queue dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"all done"); }); });
这种方法可能是最简单的,但是会带来各种限制。 例如,这将绑定一个工作线程等待另外两个发送信号,所以你必须确信你没有太多这样的请求集合并发。 你也必须确信,这些请求将调用
onSuccess
或onFailure
,但从来没有,总是一个。 这也不能真正提供取消机会或者限制自己并发程度的能力。 但是你可以用最less的代码更改来完成上述操作。 -
第二种方法是用同步请求replace你的asynchronous请求,然后你可以使用
NSOperation
标准的addDependency
逻辑:NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{ // completion operation }]; NSOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ // do fetch1 _synchronously_ }]; [queue addOperation:operation1]; NSOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ // do fetch2 _synchronously_ }]; [queue addOperation:operation2]; [completionOperation addDependencies:@[operation1, operation2]]; [queue addOperation:completionOperation];
这种方法要求你的同步抓取是线程安全的。 我不熟悉你使用的API,所以我不能说这个。
-
如果您没有可以添加到队列中的提取请求的同步呈现,则第三种方法是使用您自己的并发
NSOperation
子类来包装asynchronous获取请求,NSOperation
子类不会在asynchronous操作完成之前发出isFinished
信号(也可能是你自己的onSuccess
和onFailure
块)。 一旦你这样做了,你可以使用setDependency
function(如前面所述)来使你的第三个操作依赖于其他两个完成。 有关更多信息,请参阅“ 并发编程指南”的“ configuration并发执行的操作”部分。
我希望我能提供一个更明确的答案,但是我不太了解你的并发托pipe上下文库所需的选项/约束。
- CoreData:错误:(14)数据库的I / O错误
- 在更新UITableView中显示的CoreData模型后,应用程序崩溃
- 在一个TableView中使用2个FRC并configurationFRCDelegate
- NSFetchedResultsController在合并“NSManagedObjectContextDidSaveNotification”后没有显示所有结果
- 内存泄漏与大型核心数据批量插入在Swift中
- Xcode应用程序不释放内存
- 在代码中使用genericsInt – 在Core Data iOS中使用32或64位Int?
- 将SQL存储添加到NSPersistentStoreCoordinator时如何debugging/处理间歇性的“授权被拒绝”和“磁盘I / O”错误?
- 目标C:对象释放,而关键值观察者仍然在其上注册