dispatch_async and calling a completion handler on the original queue

grand-central-dispatch, ios, objective-c

Solution

If you look through the Apple docs, there appear to be two patterns.

If it is assumed that the completion handler is to be run on the main thread, then no queue needs to be provided. An example would be `UIView`'s `animations` methods:

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

Otherwise, the API usually asks the caller to provide a queue:

[foo doSomethingWithCompletion:completion targetQueue:yourQueue];

My suggestion is to follow this pattern. If it is unclear which queue the completion handler should be called, the caller should supply it explicitly as a parameter.

Problem

I've seen some related questions but none seem to answer this case. I want to write a method that will do some work in the background. I need this method to call a completion callback on the same thread / queue used for the original method call. ``` - (void)someMethod:(void (^)(BOOL result))completionHandler { dispatch_queue_t current_queue = // ??? // some setup code here dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ BOOL ok = // some result // do some long running processing here dispatch_async(current_queue, ^{ completionHandler(ok); }); }); ``` What magic incantation is needed here so the completion handler is called on the same queue or thread as the call to `sameMethod`? I don't want to assume the main thread. And of course `dispatch_get_current_queue` is not to be used.

Original source

Related problems