Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When you have asynchronous tasks with dependencies, you have a couple of options:</p> <ol> <li><p>The simplest solution with the least code changes is to use a semaphore:</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) { [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"); }); }); </code></pre> <p>This approach might be easiest, but entails all sorts of limitations. For example, this will tie up a worker thread waiting for the other two to send the signal, so you'd have to be confident that you don't have too many of these collections of requests going concurrently. You also have to be confident that these requests will call either <code>onSuccess</code> or <code>onFailure</code>, but never both and always one. This also doesn't really offer an cancellation opportunities or the ability to constrain the degree of concurrency yourself. But you can do the above with minimal code changes.</p></li> <li><p>The second approach would be to replace your asynchronous requests with synchronous ones, that you can then use the <code>NSOperation</code> standard <code>addDependency</code> logic:</p> <pre><code>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]; </code></pre> <p>This approach requires that your synchronous fetches are thread-safe. I'm not familiar with this API you're using, so I can't speak to that.</p></li> <li><p>If you don't have synchronous renditions of your fetch requests that you could add to the queue, the third approach would be to wrap your asynchronous fetch requests with your own concurrent <code>NSOperation</code> subclass that won't signal <code>isFinished</code> until the asynchronous operation is done (and also presumably call your own <code>onSuccess</code> and <code>onFailure</code> blocks). Once you do that, you can then use the <code>setDependency</code> functionality (as illustrated in the prior point) to make your third operation dependent upon the other two finishing. For more information, see <a href="https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW8" rel="nofollow">Configuring Operations for Concurrent Execution</a> section of the <em>Concurrency Programming Guide.</em></p></li> </ol> <p>I wish I could provide a more definitive answer, but I'm not familiar enough with the options/constraints entailed by your concurrent managed context library.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload