【iOS系列】-多图片多线程异步下载
多图片多线程异步下载
开发中非常常用的就是就是图片下载,我们常用的就是SDWebImage,但是作为开发人员,不仅要能会用,还要知道其原理。本文就会介绍多图下载的实现。
本文中的示例Demno地址,下载后项目位于iOS_Demo/09-多图片多线程下载
1 - 问题
开篇我就先将多图下载过程中出现的问题摆出来,让我们能够一一克服
。
1:下载过程要放到子线程中,否则会导致UI线程卡顿
2:图片会重复下载,我们不仅要把下载完的图片放到内存中,还要把下载队列也缓存起来,否则可能图片没有下载完,会多次创建下载队列
3:沙盒缓存,放到哪里,根据下面对沙盒文件的介绍我们需要把图片放到Library/Caches目录下。
Document : iTunes会备份
Library :
1:Caches:缓存文件,不会清除
2:Preferences:偏好设置,保存账号信息
tmp :临时路径,随时会被删除,临时的不是重要的数据
下载流程图
明白了问题后,我们需要制定战略(画流程图),这样根据流程图,下载过程就更为清晰明了。
根据流程图一些坑,我们就可以完美的避免掉了。这样写程序也更有章法。
2 - 开始下载图片
根据前面的介绍,我们需要有两个缓存对象:
- 图片data的内存缓存
- 下载队列的缓存
我们可以使用NSMutableDictionary进行缓存,
这里我们假设两个缓存对象分别是:
/** 内存中图片的缓存字典 */
@property (nonatomic,strong)NSMutableDictionary * memoryImages;
/** 下载操作的字典 */
@property (nonatomic,strong)NSMutableDictionary * operations;
2.1 内存缓存中取值
所以下载前,我们先要到内存中取值
NSData *imageData = [self.memoryImages objectForKey:url];
如果imageData
对象存在,我们就直接设置到Cell上。
2.2 内存缓存中没有,我们到沙盒中取值
内存缓存中不存在时我们到沙盒中进行查看:
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
//获取图片名字,图片名称不能包含URL,
NSString *fileName = [url lastPathComponent];
NSString *filePaPath = [path stringByAppendingPathComponent:fileName];
//内存中没有图片的缓存 -- 从沙盒中取出
NSData *imageData = [NSData dataWithContentsOfFile:filePaPath];
如果图片存在,我们需要把图片设置到Cell上,并且放一份到内存缓存中
//沙盒中取出后,放一份到内存缓存中
[self.memoryImages setObject:imageData forKey:url];
这样下次就不用频繁访问沙盒了。
2.2 内存缓存中没有,沙盒中也没有,我们需要判断下载队列是否已经存在
如果网速慢一些,并且Cell上下滑动的频率快一些的话,假如第一次第5行的Cell显示的时候,内存缓存中没有,沙盒中也没有,这时我们创建了下载对象,然后这行Cell被滑出屏幕,再次进来的时候图片还是没有下载完毕,经过判断内存缓存中没有,沙盒中也没有,我们如果再次创建下载对象的话,就会重复下载图片了,所以我们要把下载队列也进行缓存,当内存缓存中没有,沙盒中也没有时,我们先判断下载队列中是否已经存在了。
这里使用的是NSBlockOperation
NSBlockOperation *doo = [self.operations objectForKey:url];
2.2 内存缓存中没有,沙盒中也没有,下载队列也没有
这时我们就需要创建下载对象进行下载了。
首先我们先可以设置一个占位图,这样的显示更为友好一下。
NSBlockOperation *downO = [NSBlockOperation blockOperationWithBlock:^{
NSURL *uurl = [NSURL URLWithString:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *down = [session dataTaskWithURL:uurl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//图片的下载过程
}];
[down resume];
}];
同时加入下载队列
//下载对象加入队列中
[self.operations setObject:downO forKey:url];
[self.queue addOperation:downO];
图片下载完毕后,我们需要
//把图片data存入内存中
[self.memoryImages setObject:data forKey:url];
//同时写入沙盒中,永久缓存
[data writeToFile:filePaPath atomically:YES];
同时在主线程中更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
UIImage *image = [UIImage imageWithData:data];
cell.iconView.image = image;
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
这样完整的图片下载过程就好了。
【iOS系列】-多图片多线程异步下载的更多相关文章
- iOS开发网络篇—多线程断点下载
iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...
- IOS GCD图片数据异步下载,下载完成后合成显示
关于GCD使用详解,请看我的上一篇blog:http://www.cnblogs.com/xin-lang/p/6278606.html 前段时间遇到个需要异步下载,下载完成后再组合显示的东西.这里我 ...
- 使用webClient实现图片同步,异步下载
WebClient.DownloadFile 方法 将具有指定 URI 的资源下载到本地文件. 命名空间:System.Net 程序集:System(在 system.dll 中) 同步实现参考代码: ...
- iOS tableView的图片缓存异步载入
1.建立一个viewController. .h文件实现UIScrollViewDelegate和UITableViewDelegate,并声明ICTableViewDelegate(用来实现图片有缓 ...
- iOS开发网络篇—大文件的多线程断点下载
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...
- iOS开发网络篇—大文件的多线程断点下载(转)
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了 ...
- [原]unity3d之http多线程异步资源下载
郑重声明:转载请注明出处 U_探索 本文诞生于乐元素面试过程,被面试官问到AssetBundle多线程异步下载时,愣了半天,同样也被深深的鄙视一回(做了3年多u3d 这个都没用过),所以发誓要实现出来 ...
- 使用开源库 SDWebImage 异步下载缓存图片(持续更新)
source https://github.com/rs/SDWebImage APIdoc http://hackemist.com/SDWebImage/doc Asynchronous im ...
- [Xcode 实际操作]八、网络与多线程-(22)使用GCD多线程技术异步下载图片
目录:[Swift]Xcode实际操作 本文将演示如何使用使用GCD多线程技术异步下载图片. Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法 ...
随机推荐
- 本地计算机上的XXX服务启动后停止,某些服务在未由其它服务或程序使用时将自动停止
创建WindowsService,以及安装和卸载网上的资料一搜一大堆,在这里就不再做演示,只说明下博主在工作中使用WindowsService服务出现的错误,以及最终的结局方案. 1.启动window ...
- 在Windows平台搭建轻巧的Python开发环境——面向工程和科研的扩展包配置
首先,下载最新版本的Python. 为什么强调最新版本呢,因为新版本的漏洞通常会少得多,而且反映了未来的趋势. 既然要学,何不起点高一点? 官方下载地址:https://www.python.org/ ...
- HTML 5入门知识——Drag
HTML 5拖放 拖放的步骤: 1.对象元素的draggable属性设置为true,还需要注意的是a元素和img元素必须指定href. 2.编写与拖放有关的事件处理代码: DataTransfer对象 ...
- mybatis对java自定义注解的使用——入门篇
最近在学习spring和ibatis框架. 以前在天猫实习时做过的一个小项目用到的mybatis,在其使用过程中,不加思索的用了比较原始的一种持久化方式: 在一个包中写一个DAO的接口,在另一个包里面 ...
- KVC与KVO理解
转载:https://magicalboy.com/kvc_and_kvo/ KVC 与 KVO 理解 KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲 ...
- 开源的.NET定时任务组件Hangfire解析
项目慢慢就要开工了,很多园友都在问这个事情,看来大伙对这事很上心啊,事情需要一步步的来,尽量写出一个我们都满意的项目.以前每次在博客前面都会扯淡一下,不过很多人都抱怨这样做不好,加上我这人扯淡起来就停 ...
- JavaScript原型模式-理解对象
一:简述 当初学编程一看到什么什么模式就比较头晕,不过本文我们通过简单的示例代码来说一下js 对象这个话题 ,来看下如何理解这个原型模式. 二:理解对象 1.简单对象 js对象中没有java.C#等类 ...
- uploadify上传图片的类型错误的解决办法
大家在做开发的过程中,相信很多人都会使用到uploadify插件来上传图片,但是这个插件也有不完美的地方. 我曾多次遇到过这样一个问题:上传的图片类型明明是没有问题的,但是在上传的时候总是会报错:图片 ...
- UIImageView帧动画相关属性和方法
@property(nonatomic,copy) NSArray *animationImages; 需要播放的序列帧图片数组(里面都是UIImage对象,会按顺序显示里面的图片) @propert ...
- 利用firefox调试安卓手机端web
分2部分: 手机: 1.安装最新版firefox 2.打开浏览器,输入about:config 3.设置 devtools.debugger.remote-enabled 值为true devtool ...