[英]issue with dispatch_async and async request
所以第一个问题是dispatch_async
如何确定使用哪个线程? 只是随机挑选它? 我需要做一些解析和核心数据的东西,所以我不想阻止UI线程并使用dispatch_async
,但之后我发送NSURLRequest
来获取更多数据并且永远不会调用回调(可能因为线程已经死)。
那么制作它的好方法是什么? 我不能用
sendAsynchronousRequest:queue:completionHandler:
因为部署操作系统是4.现在我只是发送请求
dispatch_async(dispatch_get_main_queue(), ^{
});
它位于dispatch_async(myQueue)
块中,它执行所有解析并保存到核心数据。 但它对我来说似乎不对,我的意思是应该有一种方法来使用dispatch_async并告诉它不要杀掉它,对吗? 因为使用同步请求不是一种选择。
所以第一个问题是dispatch_async如何确定使用哪个线程?
使用GCD时,您不应该考虑线程。 这些都是幕后处理的。 您认为在队列中您传递给dispatch_async
以及要执行的块。 GCD队列会对线程进行映射,但您无需担心幕后发生的事情--GCD会为您处理所有这些事情。
至于你假设的代码看起来与此类似:
dispatch_async(myQueue, ^{
// Do some stuff off the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// Do something with the UI
});
});
这完全没有错。 您不必担心发送到myQueue
的块运行的线程可能会被终止。 队列将保持不变,直到块完成运行。 您在原始调度中调度到主队列的事实很好 - 主队列上的工作将很愉快地运行。
我想你也在问为什么在异步调度中使用NSURLRequest
时你会看到它没有调用回调。 那将是因为它紧密耦合到当前的运行循环,如果你当前在后台线程(你的myQueue
将运行),那么该运行循环将不再运行,直到另一个块被放入队列。 所以你的回调永远不会运行。
我鼓励你去阅读更多关于GCD和async vs sync实际意味着什么,因为我觉得你可能还没有完全理解它。 我在这里回答了类似的问题。
当您在块中使用sendAsynchronousRequest:...
,该块将在异步请求回调被触发之前终止。
由于您已经在后台线程中,如何在该线程中使用同步方法来获取数据 - +[NSURLRequest sendSynchronousRequest:returningResponse:error:]
,甚至更简单, +[NSData dataWithContentsOfURL:]
。
您可以在后台线程上运行的块中调用这些,并且在调用完成之前块不会继续。 然后,您可以通过回调主队列来更新UI:
dispatch_async(yourQueue, ^{
// Do some stuff
NSData * fetchedData = [NSData dataWithContentsOfURL: someURL];
// Do some more stuff with the data
dispatch_async(dispatch_get_main_queue(), ^{
// Do some stuff on the main queue
}
});
你是对的,问题是线程已经死了,因为NSURLConnection在它的生命周期内不会让它保持活着。 连接将在返回时被丢弃。 你可以用一些黑魔法明确地保持线程活着;)并在你完成后释放线程。 在这种情况下,通过在成功或出错时将_isFinishedLoading设置为true。
所以在这种情况下,使用块时不关心线程是不正确的,因为NSURLConnection并不真正兼容。 然而,块非常有用,因为框架根据底层硬件和可用资源为您选择最佳线程。
NSURLConnection* connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
[connection start];
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
_isFinishedLoading = NO;
while (!_isFinishedLoading)
{
[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.