在您的情况下,特别令人困惑的是,我们混合了一个 HTTP 请求队列(请求一个接一个地发送)和一个操作队列(一个任务接一个地执行随机计算工作)。
标准NSURLConnection
实例在主线程上调用其委托,如果您当时没有对数据或 UI 进行复杂的工作,这是可以的。但是假设您需要下载一个大文件并将其作为文件逐块写入磁盘,同时向下滚动表格视图。现在,当您在磁盘上写入数据时,您的滚动可能会变得不稳定,从而阻塞主线程。
这就是GCD
其更高级别的抽象NSOperationQueue
发挥作用的地方。要解决此问题,您需要从主线程中卸载数据写入调用。您可以通过在您的via上指定一个NSOperationQueue
实例来做到这一点。这将确保您的委托以及您的写入调用将在后台线程中调用。您还可以将委托调用留在主线程上,并将昂贵的写入调用包装在一个块中,然后您将使用. 现在基本上包装了一个调度队列,并且您通过在原始调度队列上使用它来避免额外的线程切换,所以我会推荐该解决方案(这也恰好看起来更简单)。NSURLConnection
setDelegateQueue:
dispatch_async
NSOperationQueue
NSOperationQueue
AFNetworking
是一个很棒的库,它以第三种方式解决了这个问题:它触发了一个NSThread
专门用于NSURLConnection
委托调用的库。这是从主线程卸载工作的预 GCD 方式。尽管它有效,但 GCD 提供了一种更有效和更友好的方式来向系统展示您的背景工作。
最后,如果您正在寻找 HTTP 请求队列,Cocoa 不提供它。您将不得不自己构建一个调度程序,或者您已经知道使用AFNetworking
它再次是一个不错的选择。
如果您对这个主题感兴趣,GCD 提供的不仅仅是托管NSURLConnection
委托调用,我建议您阅读 Apple 出色的并发编程指南或观看GCD 上的优秀WWDC 2011 视频( Blocks and Grand Central Dispatch in Practice和掌握大中央调度)。