【iOS系列】-多图片多线程异步下载
2017-04-15 17:14
453 查看
多图片多线程异步下载
开发中非常常用的就是就是图片下载,我们常用的就是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-UIImageView加载网络下载的图片(异步+多线程)
- iOS 开发 多线程详解之NSThread异步线程下载网络图片
- 多线程开发之NSOperation&NSOperationQueue——异步下载图片
- iOS多线程编程及简单封装图片下载
- 猫猫学iOS(五十五)多线程网络之图片下载框架之SDWebImage
- iPhone开发【十五】多线程开发之NSThread——异步下载图片
- IOS 异步下载图片
- iOS异步下载图片问题
- iOS开发多线程之队列组——下载合并图片
- ios NSThread 线程锁,多线程下载图片
- 基于iOS 使用GCD实现列表界面的图片异步下载
- 用IOS GCD异步下载图片
- iPhone开发【十七】多线程开发之NSOperation&NSOperationQueue——异步下载图片
- iOS: (库) 图片异步下载/缓存-SDWebImage的使用
- iOS学习笔记---利用NSThread实现异步更新UI和下载图片
- iOS: (库) 图片异步下载/缓存-SDWebImage的使用
- Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)
- 利用内存结构及多线程优化多图片下载(IOS篇)
- iPhone开发【十七】多线程开发之NSOperation&NSOperationQueue——异步下载图片
- ios--异步下载、显示图片