0

I have two API calls as follows :

-(void) doTask1{ 

    dispatch_async(queueSerial, ^{ //B1

     [fileObj setFileInfo:file]; 

    });
}

-(void) doTask2{ 

    dispatch_async(queueSerial, ^{ //B2

        [fileObj getFileInfo:fileName completion:^(NSError *error) {
            dispatch_async(queueSerial2, ^{
                //completion work C1
            });
         }]

    });
}

Now, my question is, from what I already understand by reading about GCD, if a process calls doTask1 and immediately after calls doTask2, it will result in both of them being queued and B1 ahead B2.

However, does is ensure that B1 is fully executed before B2 starts executing? Because the file updated by B1 is used by B2.

If B2 starts to execute before B1 is fully finished, it might result in some issues.

Or is it better to do

-(void) doTask1{ 
    dispatch_sync(queueSerial, ^{B1});
}

-(void) doTask2{ 
    dispatch_sync(queueSerial, ^{B2});
}
ExceptionHandler
  • 213
  • 1
  • 8
  • 24

3 Answers3

1

If queueSerial really is a serial queue, then B1 will complete before B2 begins. There are no guarantees concerning the relationship between those and whatever called the doTaskN methods...that would be affected by the _sync modification.

If B1 or B2 do any dispatching themselves, that's also not controlled by the serialization.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • Thanks for your comment. I have edited my question to add more details about the code. The thing that I don't understand is, your comment about "There is no guarantees concerning to the relationship between those" What does this mean? – ExceptionHandler Feb 22 '17 at 18:56
  • I mean that, in the async case, whatever code calls doTask1(), doTask2() may have gone on to do various other operations before the dispatched work is complete. In the sync case, the caller also stalls until your serial queue operations finish. – Phillip Mills Feb 22 '17 at 19:04
  • I see . I understand this part. If B2 is dispatching it's completion handler to a different queue, is it possible for this completion block to be executed before B1 has finished? Is there a way to make sure this won't happen and that the completion block in B2 waits until B1 is finished? – ExceptionHandler Feb 22 '17 at 19:10
  • It won't happen because the completion handler doesn't fire until after `getFileInfo` and `getFileInfo` is behind `setFileInfo` on the same serial queue. – Phillip Mills Feb 22 '17 at 19:18
  • Ok that makes sense. What happens if `getFileInfo` and `setFileInfo` are asynchronous methods? Will this affect the outcome? – ExceptionHandler Feb 22 '17 at 19:39
  • It will definitely affect the outcome, and how it does so depends on exactly how they become async. – Phillip Mills Feb 22 '17 at 20:04
  • I modified my original question from [here](http://stackoverflow.com/questions/42403595/forcing-the-order-of-execution-using-dispatch-sync) to be a bit cleaner and precise. Would you be able to help me figure out this one? – ExceptionHandler Feb 22 '17 at 22:57
0

If you use a serial queue your task will be finished in the same order (first in first out), but if you use concurrent you won't have any guaranty of the order that they finish.

-(void) doTask1{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    //your code
    });
}

-(void) doTask2{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    //your code
    });
}

Here are a great explanation of GCD and NSOperation for concurrency: https://www.appcoda.com/ios-concurrency/

You need to be sure that both task are send to the same queue.

Update: Another approach is to use NSOperation because you can set a dependency between task to make sure one is completed before start the other one.

Calc91
  • 124
  • 2
0

If the task, B1, which was dispatched to the serial queue, is not initiating anything asynchronous itself, then you're assured that B1 will finish before B2 starts. But if B1 is doing anything asynchronous (e.g., a network request, etc.), then you need other patterns to make sure that B2 doesn't start until B1's asynchronous task finishes (e.g. implement your own completion handlers, use dispatch_group_notify, wrap the tasks in asynchronous custom NSOperation subclasses, etc.).

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • I modified the question a bit more and created a new question [here](http://stackoverflow.com/questions/42403595/forcing-the-order-of-execution-using-dispatch-sync). Would you be able to help me figure out this one? I am not sure how I should use the `dispatch_group_notify` call here since they are 2 different methods – ExceptionHandler Feb 22 '17 at 22:59