0
votes

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});
}
3

3 Answers

1
votes

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.

0
votes

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.

0
votes

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.).