1

我发现我的 iOS 应用程序出现了最奇怪的行为。我有这个代码:

         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
             CMLog(@"Start Save RoundQuestions Asynchronously");
             [round saveRoundQuestions:target selector:selector];
         });

该函数完成它的工作并调用它:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [target performSelector:selector];
#pragma clang diagnostic pop

日志显示一切正常运行,但是目标在 navigationController 上调用了 pushViewController,并且执行实际推送需要很长时间。我可以通过单击主页按钮强制它继续。我读过我可能违反了线程安全,并且可能需要唤醒运行循环。

从 dispatch_async 调用选择器是错误的吗?还是我需要在 UI 所在的主线程上执行选择器?

编辑:我实际上发现了问题。事实证明,我正在调用一个函数,该函数阻塞了 saveRoundQuestions 内的 UI,我相信这会迫使推送动画到行的后面,可以这么说。我把这个功能放在后台,推送动画现在立即发生。但我还是很好奇为什么?

4

2 回答 2

4

您应该只在主线程上进行 UI 更新,因此您需要使用以下方法获取主队列:

dispatch_get_main_queue()

代替dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)

我的回答仍然成立,不能保证会dispatch_get_global_queue返回主线程的队列,它只是一个高优先级队列

名称: dispatch_get_global_queue
摘要:返回一个已知的给定优先级的全局并发队列。

于 2012-04-13T13:31:12.063 回答
1

您可以使用 dispatch_async 成功更新 UI。只是代替dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)使用dispatch get_main_queue()

编辑:根据您的更新。如果你在里面做一些昂贵的工作saveRoundQuestions,然后更新UI,你应该使用:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         CMLog(@"Start Save RoundQuestions Asynchronously");
         [round saveRoundQuestions:target selector:selector];
     });

然后在里面saveRoundQuestions放另一个块dispatch_get_main_queue()来更新 UI。

于 2012-04-13T13:33:02.687 回答