我创建了一个简单的测试应用,以了解如何使用NSURLSession
。此应用程序必须从Web服务下载图像并将其显示为UITableView
。
我已经编写了应用程序的第一部分,它从Web服务中读取了一个图像URL列表,现在,我想显示这个列表。
我怀疑是:
鉴于图像列表可能是一个非常长的列表,是否可以为每个图像创建NSURLSessionDownloadTask
?
我想在cellForRowAtIndexPath
函数中创建会话并将NSURLSessions存储在NSDictionary中,使用单元格的IndexPath
作为关键字(并且可能依赖于NSURLCache
以避免下载相同的图像不止一次)。
其他解决方案:
我可以看到另外三个解决方案:
将GCD
与dispatch_async
对NSOperation进行子类化,并为我需要下载的任何图片存储NSOperation
。
使用像AFNetwork
这样的第三方库...但由于它是一个学习用途的应用程序,我更喜欢完全使用我的代码
如果多个NSURLSession不是一个好的解决方案,我选择其中一个选项。
您如何看待这种方法?
答案 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)
我会使用(或至少看看)SDWebImage的SDWebImageManager
。
除了下载,你可以设置优先级并继续我认为你想要的后台选项。