菜鸟教程小白 发表于 2022-12-13 05:28:36

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


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

<p><strong>FetchRequest 1:</strong></p>

<pre><code> [self.managedObjectContext executeFetchRequest:fetchRequest1 onSuccess:^(NSArray *results) {
      //Succcess
      ;

    } onFailure:^(NSError *error) {
      ;
    }];
</code></pre>

<p><strong>FetchRequest 2:</strong></p>

<pre><code> [self.managedObjectContext executeFetchRequest:fetchRequest2 onSuccess:^(NSArray *results) {
      //Succcess
      ;

    } onFailure:^(NSError *error) {
      ;
    }];
</code></pre>

<p>我想等到获取请求 <strong>1</strong> 和 <strong>2</strong> 都完成后再调用另一个方法。</p>

<p>我可以使用 <code>NSOperationQueue</code> 来监控这两个 block 吗?如果没有,知道两个 block 何时完成的最佳方法是什么? </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>当您有具有依赖关系的异步任务时,您有两种选择:</p>

<ol>
<li><p>代码更改最少的最简单解决方案是使用信号量:</p>

<pre><code>// create a semaphore

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

// initiate two requests (signaling when done)

[self.managedObjectContext executeFetchRequest:fetchRequest1 onSuccess:^(NSArray *results) {
    ;
    dispatch_semaphore_signal(semaphore);
} onFailure:^(NSError *error) {
    ;
    dispatch_semaphore_signal(semaphore);
}];

[self.managedObjectContext executeFetchRequest:fetchRequest2 onSuccess:^(NSArray *results) {
    ;
    dispatch_semaphore_signal(semaphore);
} onFailure:^(NSError *error) {
    ;
    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(@&#34;all done&#34;);
    });
});
</code></pre>

<p>这种方法可能最简单,但也存在各种限制。例如,这将占用一个等待其他两个发送信号的工作线程,因此您必须确信您没有太多的这些请求集契约(Contract)时进行。您还必须确信这些请求将调用 <code>onSuccess</code> 或 <code>onFailure</code>,但绝不会同时调用两者,并且始终调用一个。这也没有真正提供取消机会或自己限制并发程度的能力。但是您可以通过最少的代码更改来完成上述操作。</p></li>
<li><p>第二种方法是将异步请求替换为同步请求,然后您可以使用 <code>NSOperation</code> 标准 <code>addDependency</code> 逻辑:</p>

<pre><code>NSOperationQueue *queue = [ init];

NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
    // completion operation
}];

NSOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    // do fetch1 _synchronously_
}];

;

NSOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    // do fetch2 _synchronously_
}];

;

];
;
</code></pre>

<p>这种方法要求您的同步提取是线程安全的。我对你使用的这个 API 不熟悉,所以我不能说。</p></li>
<li><p>如果您没有可以添加到队列中的获取请求的同步再现,第三种方法是使用您自己的并发 <code>NSOperation</code> 子类包装您的异步获取请求在异步操作完成之前不会发出 <code>isFinished</code> 信号(并且可能还会调用您自己的 <code>onSuccess</code> 和 <code>onFailure</code>block )。一旦你这样做了,你就可以使用 <code>setDependency</code> 功能(如前一点所示)使你的第三个操作依赖于其他两个完成。如需更多信息,请参阅 <a href="https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW8" rel="noreferrer noopener nofollow">Configuring Operations for Concurrent Execution</a> <em>并发编程指南部分。</em></p></li>
</ol>

<p>我希望我能提供一个更明确的答案,但我对您的并发托管上下文库所包含的选项/约束不够熟悉。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 当两个单独的 NSFetchRequest 都完成时采取行动,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/19919771/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/19919771/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 当两个单独的 NSFetchRequest 都完成时采取行动