Runloop not processing events from dispatch_async

1.9k views Asked by At

I'm having some issues using dispatch_async. On my applications main/UI thread, I call dispatch_async on the global queue, and tell it to go do some function call which has a completion handler. I'm expecting the completion handler to get called but it does not appear to sometimes.

dispatch_queue_t hiq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(hiq, ^(void){
            [object doSomethingAndThenCompletionHandler:^(){
                //Do some stuff because I'm done
            }];
        });

What is interesting is, I'm doing this in response to a controlTextDidChange whenever I type something into a textfield. When I click out of the textfield, all of the completion handlers fire at once.

My guess is that all of my completion handlers are getting queued up behind something on the run loop and then when my UI element loses focus, that frees up the queue. I'm not enough of an expert on run loops to know what exactly is happening as I'm typing in a textfield or combobox but perhaps it's tying up the runloop?

EDIT: I think it has to do with the run loop mode because when I print out the run loop mode it prints out as NULL except for in the completion handler when it prints out as the default mode. I'm using a combo box and the issue is only present when the combobox is open and expanded. UIScrollView blocks run loop? I think it might have to do with this issue. What do you guys think?

2

There are 2 answers

0
JPC On BEST ANSWER

Figured out the issue I think. Some of the libraries I'm using are most likely sending NSURLConnections out without scheduling to run in common run loop modes. When the combo box is open the run loop mode changes to event tracking mode and then can't get call backs for them.

10
rob mayoff On

When you do [[NSRunLoop currentRunLoop] runUntilDate:fiveSecondsFromNow], it enters the run loop recursively, and the run loop processes events normally. So it will call your method again if the text field receives another event. The stack trace would look something like this (with lots more frames related to NSRunLoop):

main
NSApplicationMain
-[NSRunLoop runUntilDate:]
your method
-[NSRunLoop runUntilDate:]
your method

I have no idea why you're calling runUntilDate:, but it's probably not for a good reason.

If you want help understanding why your completion handler isn't getting called, then you need to show us the definition of your doSomethingAndThenCompletionHandler: method.