使用NSURLSession下载大量图像

时间:2014-06-27 09:41:52

标签: ios cocoa-touch

我创建了一个简单的测试应用,以了解如何使用NSURLSession。此应用程序必须从Web服务下载图像并将其显示为UITableView。 我已经编写了应用程序的第一部分,它从Web服务中读取了一个图像URL列表,现在,我想显示这个列表。

我怀疑是:

鉴于图像列表可能是一个非常长的列表,是否可以为每个图像创建NSURLSessionDownloadTask? 我想在cellForRowAtIndexPath函数中创建会话并将NSURLSessions存储在NSDictionary中,使用单元格的IndexPath作为关键字(并且可能依赖于NSURLCache以避免下载相同的图像不止一次)。

其他解决方案

我可以看到另外三个解决方案:

  1. GCDdispatch_async

  2. 一起使用
  3. 对NSOperation进行子类化,并为我需要下载的任何图片存储NSOperation

  4. 使用像AFNetwork这样的第三方库...但由于它是一个学习用途的应用程序,我更喜欢完全使用我的代码

  5. 如果多个NSURLSession不是一个好的解决方案,我选择其中一个选项。

    您如何看待这种方法?

4 个答案:

答案 0 :(得分:6)

NSURLSessionTask适用于大量下载。与您提到的其他一些方法相比,它的一个优点是可以取消或暂停下载。它还正确地实现了网络操作的并发性,这比互联网上的许多猫更难以让您相信(如果您不相信我,请查看eskimo的2010 WWDC会话和示例代码。网络连接的NSOperation并非无足轻重)。

NSURLSessionTask和朋友专为您要解决的问题而设计,并且经过了很好的测试。

对于tableview,在tableView:willDisplayCell:forRowAtIndexPath:中启动任务并取消(或暂停)tableView:didEndDisplayingCell:forRowAtIndexPath:中的任务。这会将活动下载限制为当前可见的单元格。

答案 1 :(得分:3)

<强>建议:

我也遇到了类似的情况,我需要下载大约2000个图像文件和100个视频文件。为此,我使用NSOperationQueue和阻止实现了自定义下载管理器。

我已将此库添加到GitHub,请随时检查实施情况。

答案 2 :(得分:1)

IMO虽然可以为每个图像创建一个NSURLSessionTask,但在滚动细胞时,标准先进先出实施会导致问题。这样做的原因是下载将在NSURLSession上排队,任务将按照它们添加到队列的顺序执行,换句话说就是以FIFO方式执行。想象一下,您已经滚动浏览了大量单元格,并且必须等待所有下载按顺序完成。您不仅需要等待很长时间,还会对可能与您的用户无关的图片资产进行不必要的网络请求。

Nick Lockwood创建了一个名为NSOperationQueue的伟大NSOperationStack子类,它颠倒了操作的顺序,以便首先执行最后一个操作(LIFO)。对于大量下载的IMO来说,LIFO的实现是必须的。

NSOsperationStack可用here

如果您将此与使用cellForRowAtIndexPath启动和NSURLCache存储下载的实现相结合,那么您应该最终获得一个非常简化且高效的解决方案。

答案 3 :(得分:1)

我会使用(或至少看看)SDWebImageSDWebImageManager

除了下载,你可以设置优先级并继续我认为你想要的后台选项。