4

I am trying to process method asynchronously, as per requirements, once the first method has completed, only then the second method should start executing. The Problem is first method itself has code that runs on background thread.

I tried dispatch_semaphore_wait, but that didnt work either.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

        dispatch_group_t group = dispatch_group_create();


        dispatch_group_async(group, queue, ^{

            [self firstMethod];
            NSLog(@"firstMethod Done");

        });
        dispatch_group_notify(group, queue, ^ {

            NSLog(@"1st method completed");
            NSLog(@"2nd method starting");

            [self secondMethod];

        });

FirstMethod itself runs on another worker thread like this

-(void)firstMethod
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
   //processing here.....       

 }];

What is the best way to achieve it, I cannot change the definition of firstMethod as it provided by some 3rd party and also changing it means changing lots of existing code from where this method is being called

iHS
  • 5,372
  • 4
  • 31
  • 49
  • 3
    There's basically no way to do what you're asking unless the 3rd party library provides some way to detect when that private block finishes executing. Does it? – rob mayoff May 09 '13 at 23:01
  • rob:no, it doesnot provide any way to find when that private block finishes – iHS May 09 '13 at 23:18
  • Can you summarize what the private async block does? Especially note any filesystem / network interaction. – sounder_michael May 24 '13 at 20:03
  • For a generic way to execute asynchronous tasks that DO report when they're done in sequence, see http://stackoverflow.com/questions/16226727/how-to-cleanly-encapsulate-and-execute-in-sequence-a-series-of-background-tasks – flup May 29 '13 at 10:17

2 Answers2

12

You can use a completion block. You just need to modify firstMethod this way:

- (void)firstMethodWithOnComplete:(void (^)(void))onComplete {
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
          //processing here.....
          onComplete();
       });
}    

And then use it this way:

[self firstMethodWithOnComplete:^{
    [self secondMethod];
}];
robbartoszewski
  • 896
  • 6
  • 11
  • Seems like good alternate, but the firstMethod is in different library and modifying it will need to change in lots of classes. Is there any other solution? – iHS May 09 '13 at 22:33
  • Would adding a property to the class which implements firstMethod be easier? In such case you can use delegate pattern. I can elaborate on that if needed. – robbartoszewski May 09 '13 at 22:56
-1

Dispatch a Single Queue and call your Methods in order

dispatch_group_async(group, queue, ^{

            [self firstMethod];
            NSLog(@"firstMethod Done");
           [self secondmethod];

        });

Or you might dispatch a group of 3 concurrent queues(This is a Wild guess)

Dheeraj Kaveti
  • 171
  • 1
  • 2
  • 10
  • 1
    This wont work as firstMethod has it own dispatch_async call in its definition, and [self secondmethod]; wont wait for [self firstMethod]; to finish – iHS May 09 '13 at 22:22