GCDAsyncSocket 在接收数据时冻结 UI
Posted
技术标签:
【中文标题】GCDAsyncSocket 在接收数据时冻结 UI【英文标题】:GCDAsyncSocket freezes UI when receiving data 【发布时间】:2015-04-10 15:39:26 【问题描述】:我是 GCD 原理和 GCDAsyncSocket 的新手,但我在我的项目中使用它。我在 AppDelegate 中初始化 GCD 套接字:
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
现在,一切正常,发送和接收工作正常。但是,如果套接字非常快地接收到大量数据(例如来自服务器的“for循环”的大约 1000 条消息),则应用程序的 UI 会冻结,直到它接收到所有内容(尽管接收到的消息中没有错误) .
那么我需要进行哪些更改才能不让 UI 冻结?是因为它使用“dispatch_get_main_queue()”,我需要使用另一个队列吗?如果是这样,我应该怎么做?还是我使用线程或类似的东西?
【问题讨论】:
【参考方案1】:尝试创建自己的并发串行后台队列(结果你不允许使用并发的),例如
dispatch_queue_t queue = dispatch_queue_create("com.yourid.queue", DISPATCH_QUEUE_SERIAL);
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue: queue];
您也可以传递“NULL”,GCDAsyncSocket 将创建自己的队列。
这应该调用后台队列中的委托方法,并希望阻止您的 UI 冻结。这里需要注意的重要一点是,您不能在后台队列中更新 UI 元素,因此您必须在委托方法中执行类似的操作:
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
//Do some calculations (in background queue)
dispatch_async(dispatch_get_main_queue(), ^
//Update UI elements (in main queue)
);
(希望我没记错)
【讨论】:
我阅读了 GCD 文档并自己解决了这个问题。唯一的区别是您创建的自定义调度队列是并发的,我相信 GCDAsyncSocket 委托队列需要是串行的(以便所有传入/传出消息一个接一个地串行处理)。因此,串行的在我的实现中运行良好,但我还没有测试并发的。如果您可以向我保证并发的也可以,我会将此答案标记为正确的。 我做了更多研究并编辑了我的答案。原来你不允许使用并发队列...以上是关于GCDAsyncSocket 在接收数据时冻结 UI的主要内容,如果未能解决你的问题,请参考以下文章
无法接收使用 GCDAsyncSocket 发送的 UDP 数据包的响应
GCDAsyncSocket 未接收到所有传输的数据,缺少最后一个“块”