Rafael Nobre
Rafael Nobre

Reputation: 5131

Calling code sequentially after dispatch_async

I'm doing some customization in iOS, I'm subclassing a system class that executes a method asynchronously (presumably with dispatch_async) Sample code:

-(void)originalAsyncMethod {
    [super originalAsyncMethod];
    dispatch_async(dispatch_get_main_queue(), ^{
      //do something that needs to happen just after originalAsyncMethod finishes executing
    });
  }

Is there a way I can make sure my custom code runs AFTER the async super method is executed?

Upvotes: 2

Views: 470

Answers (1)

Mick MacCallum
Mick MacCallum

Reputation: 130183

It's unclear to me wether this would be possible based on your question, but if you have direct access to the implementation of super, then this shouldn't be to hard to achieve.

First, assuming that you have access to the super class and that the super implementation also dispatches asynchronously to the main queue, then you don't actually have to do anything to get this working expectedly. When you use dispatch_get_main_queue() you're adding your dispatch block to the end of a serial queue on the main thread that is executed in FIFO (first in first out) order.

The second option is also pretty heavily reliant on having access to the super implementation, as it would require you manually create your own dispatch queue to execute tasks on. I think it goes without saying that if you use a serial dispatch queue then you have FIFO ordering in this queue same as you dispatch_get_main_queue(), only you wouldn't have to execute on the main thread.

And the last option I can think of wouldn't necessarily require you to modify the super class, but would require you to know the queue on which super was executing. (and still might not work right if it's a global queue) By using a dispatch_barrier, you could allow your super implementation to execute asynchronously on a concurrent queue knowing that the subclass dispatch block has also been added to the queue (via dispatch_barrier), and will be executed once the super dispatch (and any other previous submissions to the queue) has completed.

Quoting the docs

A dispatch barrier allows you to create a synchronization point within a concurrent dispatch queue. When it encounters a barrier, a concurrent queue delays the execution of the barrier block (or any further blocks) until all blocks submitted before the barrier finish executing. At that point, the barrier block executes by itself. Upon completion, the queue resumes its normal execution behavior.

Upvotes: 2

Related Questions