gpt4 book ai didi

ios - 当两个单独的 NSFetchRequests 都完成时采取行动

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:44:51 24 4
gpt4 key购买 nike

我正在使用带有 Core Data 的远程数据库,当我执行以下提取请求时,根据互联网连接,可能需要一些时间。我想监控这两个请求,当它们完成时——无论是成功还是失败——我想触发另一种方法。

获取请求 1:

 [self.managedObjectContext executeFetchRequest:fetchRequest1 onSuccess:^(NSArray *results) {
//Succcess
[self.refreshControl endRefreshing];

} onFailure:^(NSError *error) {
[self.refreshControl endRefreshing];
}];

获取请求 2:

 [self.managedObjectContext executeFetchRequest:fetchRequest2 onSuccess:^(NSArray *results) {
//Succcess
[self.refreshControl endRefreshing];

} onFailure:^(NSError *error) {
[self.refreshControl endRefreshing];
}];

我想等到提取请求 12 都完成后再调用另一个方法。

我可以使用 NSOperationQueue 来监控这两个 block 吗?如果没有,知道两个区 block 何时完成的最佳方法是什么?

最佳答案

当你有带有依赖的异步任务时,你有几个选择:

  1. 代码更改最少的最简单解决方案是使用信号量:

    // 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");
    });
    });

    这种方法可能是最简单的方法,但会带来各种限制。例如,这将占用一个等待其他两个线程发送信号的工作线程,因此您必须确信您不会同时处理太多这些请求集合。您还必须确信这些请求将调用 onSuccessonFailure,但永远不会同时调用两者。这也并没有真正提供取消机会或自己限制并发程度的能力。但您可以通过最少的代码更改来完成上述操作。

  2. 第二种方法是将异步请求替换为同步请求,然后您可以使用 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,所以我不能说。

  3. 如果您没有可以添加到队列中的获取请求的同步再现,第三种方法是使用您自己的并发 NSOperation 子类包装您的异步获取请求在异步操作完成之前不会发出 isFinished 信号(并且可能会调用您自己的 onSuccessonFailure block )。一旦你这样做了,你就可以使用 setDependency 功能(如前一点所示)使你的第三个操作依赖于其他两个完成。有关详细信息,请参阅 Configuring Operations for Concurrent Execution 并发编程指南部分。

我希望我能提供更明确的答案,但我对并发托管上下文库所包含的选项/约束还不够熟悉。

关于ios - 当两个单独的 NSFetchRequests 都完成时采取行动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19919771/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com