列表的单元格中包含有图片在开发中很常见。通常我们可以直接在tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)中给单元格设置图片。
但有时这些图片要从远程加载,或者要给图片作裁减,添加滤镜等操作。如果这些操作还是直接在主线程中进行,由于上下拖动表格滚动条的时候,单元格渲染是实时进行的。那么单元格便会不断地进行图片加载,渲染,影响效率造成卡顿。如果图片大的话还会浪费流量。
下面通过一个展示“热门电影”表格,演示如何进行优化。
1,最初的代码 这个是功能的最简单实现,后面我们要在这个基础上进行改进。 UITableView里除了显示文字,还从网络下载海报图片。同时为了使CPU资源占用更明显,还给图片添加了棕褐色滤镜。 由于这些都在主线程操作,可以发现滚动表格的时候,界面比较卡。(而且下载过的图片由于没有保存本地,来回拖动滚动条会发现图片在重复下载。)
movies.plist - 存储电影名字和对应的海报url地址 (下面是部分代码片断)
ListViewController.swift - 主页面代码
源码下载:T1.zip
2,功能改进:使用后台线程进行图片下载,和滤镜添加 (1)通过使用NSOperation和NSOperationQueue,创建两个队列。一个用来下载图片,一个用来处理图片。由于这些不在主线程中进行,所以拖动滚动条的时候就不会卡顿了。 (2)下载和滤镜是分别实现,因为有可能在图片下载时,用户将图片划动出屏幕了,这时不会再添加滤镜。当下一次用户划到当前行时,就不需要再下载图片了;只需要添加滤镜!这样可以提高效率。 (3)为便于观察,这里将maxConcurrentOperationCount设置为1。表示一个队列中同时只有一个线程运行。(实际应用中可根据情况多开几个线程) (4)开始的时候,会显示默认占位图片。图片下载成功后,会替换显示真实图片。图片下载失败,则显示失败图片。滤镜处理完毕后,替换显示处理后的图片。 (5)为增强用户体验,刚开始单元格尾部附件图片是一个转圈动画。一旦图片处理完毕或下载失败,便将其去除。
(1)电影条目类和状态枚举 - MovieRecord.swift
(2)队列管理类 - MovieOperations.swift
(3)图片下载操作任务类 - ImageDownloader.swift
(4)滤镜处理任务类 - ImageFiltration.swift
(5)主页代码 - ListViewController.swift
源码下载:T2.zip
3,功能再次改进:拖动滚动条的时候不加载,停止后只加载当前页 当滚动表格时,比如快速的滚动到最后一条数据。虽然前面的单元格都已移出可视区域。但其实这些图片的下载和处理任务已经添加到后台队列中,并默默地在执行。 (1)解决这个问题,就要保证表格在滚动的情况下,不添加任务到队列中。而且只有当表格停止后,只把当前可见区域的图片添加到任务队列中。 (2)同时,对于那些原来在可视区域的队列任务。如果对应单元格被移出可视区域,那么其任务也要取消。
只需在主页面代码里稍作修改即可:源码下载:T3.zip
原文出自:转载请保留原文链接:/blog/cache/detail_890.html
如果觉得《Swift - 表格图片加载优化(拖动表格时不加载 停止时只加载当前页图片)》对你有帮助,请点赞、收藏,并留下你的观点哦!