Async NSURLConnection 触发其他 Async NSURLConnection:最好的方法是什么?

Async NSURLConnection triggering other Async NSURLConnection: what is the best way of doing this?

这是一个开放式问题,旨在了解什么是我认为可能常见的问题的最佳实践或最常见的解决方案。

假设我有 URL 的列表要下载;该列表本身托管在服务器上,因此我启动了一个 NSURLConnection 来下载它。 connectionDidFinishLoading 中的代码将使用 URL 的列表来实例化一个新的 NSURLConnection,异步地,每个 URL;这反过来会触发更多的 NSURL 连接,依此类推 - 直到不再有 URL。将其视为连接树。

检测所有连接何时完成的最佳方法是什么?

我的目标是 iOS7,但欢迎对其他版本发表评论。

您应该考虑使用 NSOperationQueue 而不是使用 GCD。您还应该将并发操作的数量(当然是在移动设备上)限制为 4,这样您就不会用请求淹没网络。

现在,队列上的操作数就是剩余的计数。您可以在每个操作的末尾添加一个块来检查队列计数并执行任何完成逻辑。

几个想法:

  1. 关于从服务器检索列表后触发后续下载,只需将执行这些后续下载的逻辑放在第一个请求的完成处理程序块(或完成委托方法)中.

  2. 在下载一堆文件方面,如果目标是 iOS 7 及更高版本,您可以考虑使用 NSURLSession 而不是 NSURLConnection

    • 首先,通过启动 "download" 任务(而不是 "data" 任务)可以下载具有适度内存占用的文件。

    • 其次,您可以使用后台 NSURLSessionConfiguration 进行下载,这样即使用户离开应用程序也可以继续下载。请参阅 iOS 的 应用程序编程指南的 Downloading Content in the Background 部分。 如果您这样做,有很多 i's 需要点和 t's 需要交叉,但是这是一个值得考虑实施的重要功能。

    参见 WWDC 2013 What's New in Foundation Networking for an introduction to NSURLSession. Or see the relevent chapter of the URL Loading System Programming Guide

  3. 在跟踪是否完成方面,正如 Wain 所建议的,您可以只跟踪发出的请求数和请求数 completed/failed,并且在您的 "task completion" 逻辑,只需比较这两个数字,如果完成数与请求数匹配,则启动 "all done" 逻辑。有很多方法可以做到这一点,在某种程度上取决于您的实施细节,但希望这能说明基本思想。

正如 Rob 在他的回答中所说,您可能需要考虑 NSURLSession 而不是自己这样做。它有很多优点。

其他选项是构建您自己的下载管理器class,或使用现成的第三方框架,如 AFNetworking。我只使用过 AFNetworking 一点点,但据我所知,它优雅、强大且易于使用。

我们公司为一个早于 AFNetworking 和 NSURLSession 的项目编写了一个基于 NSURLConnection 的异步下载管理器 class。这并不难,但不如 NSURLSession 或 AFNetworking 灵活。