GCDAsyncSocket 在接收数据时冻结 UI
GCDAsyncSocket freezes UI when receiving data
我是 GCD 原理和 GCDAsyncSocket 的新手,但我正在我的项目中使用它。我在 AppDelegate 中初始化 GCD 套接字:
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
现在,一切正常,收发正常。但是,如果套接字非常快地接收到大量数据(比如来自服务器 'for loop' 的 1000 条左右的消息),应用程序的 UI 会冻结,直到它接收到所有数据(尽管没有错误在收到的消息中)。
那么我需要更改什么才能不让 UI 冻结?是不是因为用的是"dispatch_get_main_queue()",需要用别的队列吗?如果是这样,我应该怎么做?还是我使用线程或类似的东西?
尝试创建您自己的并发串行后台队列(事实证明您不允许使用并发队列),例如
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 的新手,但我正在我的项目中使用它。我在 AppDelegate 中初始化 GCD 套接字:
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
现在,一切正常,收发正常。但是,如果套接字非常快地接收到大量数据(比如来自服务器 'for loop' 的 1000 条左右的消息),应用程序的 UI 会冻结,直到它接收到所有数据(尽管没有错误在收到的消息中)。
那么我需要更改什么才能不让 UI 冻结?是不是因为用的是"dispatch_get_main_queue()",需要用别的队列吗?如果是这样,我应该怎么做?还是我使用线程或类似的东西?
尝试创建您自己的并发串行后台队列(事实证明您不允许使用并发队列),例如
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)
});
}
(希望我没记错)