2015-04-17 57 views
-2

我对GCD很新,我不确定我是否做错了什么。我的代码是这样的:dispatch_async仍然阻止我的用户界面

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       if([manager updateRecord:foodRecord]) // this function will connect to a web server, and might take a few seconds. If I remove it, the UI will be smooth as butter 
       { 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         [cell expandAnimation]; // this function calls a series of UIView animateWithDuration to basically scale the cell and then call a reloadData when it's done 
        }); 
       } 
      }); 

任何想法为什么它仍然会导致同步行为?我尝试使用GCD之前和之后似乎没有区别。

+1

这种“同步行为”究竟是什么?你是说在这个dispatch_async后面没有一行代码吗?无论如何,这个问题并不在上面的代码中。也许在'updateRecord'方法中。如WWDC 2012视频[在iOS上构建并发用户界面](https://developer.apple.com/videos/wwdc/2012/?id=211)中所示,您可以随时使用“记录等待线程”选项。 – Rob

+0

管理器的-updateRecord方法是线程安全的吗?如果不是这样,你是否在同一个线程上实例化和访问经理资源? – bteapot

+0

请在'updateRecord'方法中分享你的代码..似乎有一些问题。 – itsji10dra

回答

0

我不确定你的“同步行为”的想法是什么,但dispatch_async模式的主要好处是,动画(如tableView滚动和其他转换)可以继续而不会出现口吃和结束用户应用程序感觉响应。在5秒钟的Web服务器调用完成之前,它将无法显示更多数据或根据可用数据更新UI。

也许您需要在第一次dispatch_async调用之前使用“加载数据”类型消息更新单元格或显示活动指示符,以通知用户。

然后在开始dispatch_async之后,用户在等待< 5秒钟时仍然应该对用户感觉响应(例如可滚动的tableView等)。然后在dispatch_async回到主队列中,这个“加载”UI状态可以被删除(在这里插入设计器魔术),然后打电话给你的[cell expandAnimation];完成它。

如果你仍然看到用户界面上出现口吃,那么[manager updateRecord:foodRecord]可能会对返回的网页数据进行非常繁重的处理,这可以用TimeProfiler工具进行进一步调查,但我认为这是一个单独的问题。

+0

谢谢,您的回答为我提供了一些非常有用的信息。 – CyberMew

0

问题不在于上面显示的gcd代码或用户代码。

问题是另一个侦听指令的套接字,并且在调用updateRecord方法时,套接字也正在接收一些正在主线程上执行的指令。这不是即时的,因此gcd代码由于某种原因而不起作用的错觉。这也增加了解决问题的难度,因为上面的代码与问题没有直接关系。

因此,如果您正在阅读本文,请更广泛地考虑您的应用程序如何工作(内部),并检查应用程序中还有哪些应用程序正在运行!