我在使用dispatch_async时遇到一些问题。在我的应用程序主/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元素失去焦点时,就会释放队列。我不是一个足够的运行循环专家,不知道当我在文本字段或组合框中键入时到底发生了什么,但也许它会占用运行循环?
EDIT:我认为这与运行循环模式有关,因为当我打印出运行循环模式时,除了在完成处理程序中打印为默认模式时,它会打印为NULL。我使用的是组合框,只有当组合框打开并展开时,问题才会出现。UIScroll是否查看块运行循环?我认为这可能与这个问题有关。你们觉得怎么样?
当您执行[[NSRunLoop currentRunLoop] runUntilDate:fiveSecondsFromNow]
时,它会递归地进入运行循环,运行循环会正常处理事件。因此,如果文本字段接收到另一个事件,它将再次调用您的方法。堆栈跟踪看起来像这样(有更多与NSRunLoop相关的帧):
main
NSApplicationMain
-[NSRunLoop runUntilDate:]
your method
-[NSRunLoop runUntilDate:]
your method
我不知道你为什么叫runUntilDate:
,但这可能不是有充分理由的。
如果您想了解为什么您的完成处理程序没有被调用,那么您需要向我们展示doSomethingAndThenCompletionHandler:
方法的定义。
解决了我认为的问题。我使用的一些库很可能发送NSURLConnection,而不安排在常见的运行循环模式下运行。当组合框打开时,运行循环模式将更改为事件跟踪模式,然后无法获得它们的回调。