Runloop不处理来自dispatch_async的事件

时间:2012-01-07 21:59:02

标签: objective-c cocoa objective-c-blocks grand-central-dispatch runloop

我在使用dispatch_async时遇到了一些问题。在我的应用程序main / UI线程上,我在全局队列上调用dispatch_async,并告诉它去做一些具有完成处理程序的函数调用。我期待完成处理程序被调用,但有时似乎没有。

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

有趣的是,每当我在文本字段中输入内容时,我都是在响应controlTextDidChange时这样做的。 当我点击文本字段时,所有完成处理程序都会立即触发。

我的猜测是我的所有完成处理程序都在运行循环中排队等待,然后当我的UI元素失去焦点时,释放队列。我不是一个关于运行循环的专家,因为我在输入文本字段或组合框时知道究竟发生了什么,但也许它会占用runloop?

编辑:我认为它与运行循环模式有关,因为当我打印出运行循环模式时,它打印为NULL,除了在完成处理程序中打印出默认模式时。我正在使用一个组合框,只有当组合框打开并展开时才会出现问题。 UIScrollView blocks run loop?我认为这可能与此问题有关。你们觉得怎么样?

2 个答案:

答案 0 :(得分:1)

执行[[NSRunLoop currentRunLoop] runUntilDate:fiveSecondsFromNow]时,它会递归进入运行循环,并且运行循环正常处理事件。因此,如果文本字段收到另一个事件,它将再次调用您的方法。堆栈跟踪看起来像这样(有更多的帧与NSRunLoop相关):

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

我不知道你为什么打电话给runUntilDate:,但这可能不是一个很好的理由。

如果您想了解为什么没有调用完成处理程序的帮助,那么您需要向我们展示doSomethingAndThenCompletionHandler:方法的定义。

答案 1 :(得分:0)

想出我认为的问题。我正在使用的一些库很可能在没有安排在常见的运行循环模式下运行的情况下发送NSURLConnections。当组合框打开时,运行循环模式将更改为事件跟踪模式,然后无法为它们进行回调。