OC - 20.多图下载
效果图

常见问题及解决方法
图片重复下载
- 将内存保存在内存或沙盒中。
若下载的图片量较大,则会出现UI界面不流畅的现象
- 在子线程中执行下载操作,然后回到主线程成中进行UI界面的刷新。
由于cell的循环利用造成的图片显示错乱问题
- 指定刷新表格的indexPath行。
subTitle类型的cell,无法显示图片
- subtitle类型的cell中的imageView只有在第一次返回cell时设置图片,否则图片将不能显示(刷新表格也不行)。可以通过设置占位图片的方式来解决此问题。
思维导图

具体实现
其核心代码主要在tableView的返回创建cell的代理方法中,所以以下主要对该方法的实现进行解析
主要流程
设置模型类,包含以下属性
/**图片*/
@property (nonatomic, strong) NSString *icon;
/**名字*/
@property (nonatomic, strong) NSString *name;
/**下载量*/
@property (nonatomic, strong) NSString *download;需要用到的成员属性
/**模型数组,用来存放每个cell的数据模型*/
@property (nonatomic, strong) NSArray *apps;
/**操作队列,操作只有添加到队列才有可能并发执行*/
@property (nonatomic, strong) NSOperationQueue *queue;
/**用于在内存中缓存图片,部分避免图片被多次下载*/
@property (nonatomic, strong) NSMutableDictionary *imageCache;
/**标记当前所有正在执行的操作,避免正在执行的操作被重复执行*/
@property (nonatomic, strong) NSMutableDictionary *operations;创建cell的方法的核心代码
从内存缓存中取图片
//内存中缓存的图片在imagCache数组中
self.imageCache[app.icon]从沙盒中取图片
//获取文件路径
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
//获取文件名
NSString *filename = [app.icon lastPathComponent];
//计算出全路径
NSString *file = [cachePath stringByAppendingPathComponent:filename];
//加载沙盒中的数据
NSData *data = [NSData dataWithContentsOfFile:file];
//判断data中若有数据,否则从网络上下载数据
if (data)
{//沙盒中有数据
UIImage *image = [UIImage imageWithData:data];
cell.imageView.image = image;
//存到字典中(即内存)
self.imageCache[app.icon] = cell.imageView.image;
}从网络上下载数据
//若subTitle类型的cell要显示图片,必须在第一次放回cell时就显示图片(或占位图片)
cell.imageView.image = [UIImage imageNamed:@"1"];
//取得操作队列中的操作
NSOperation *operation = self.operations[app.icon];
if (operation == nil)
{//不存在该图片的下载操作
//创建下载图片操作
operation = [NSBlockOperation blockOperationWithBlock:^{
//通过url加载数据
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];
//数据加载失败
if (data == nil)
{
//移除操作,以便刷新表格时能够再次请求数据
[self.operations removeObjectForKey:app.icon];
return ;
}
//NSData转换为UIImage
UIImage *image = [UIImage imageWithData:data];
//存放到字典中
self.imageCache[app.icon] = image;
//线程睡眠,模拟大数据下载
[NSThread sleepForTimeInterval:1];
//回主线程显示图片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//通过indexPath刷新表格,此时内存缓存中已有图片
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
//将图片写入沙盒
[data writeToFile:file atomically:YES];
//移除操作,保证在刷新表格时可以重新下载没有下载的图片
[self.operations removeObjectForKey:app.icon];
}];
//将操作添加到队列
[self.queue addOperation:operation];
//保证图片不被重复下载
self.operations[app.icon] = operation;
通过第三方框架(SDWebImage)
- SDWebImage可以大大简化多图下载任务
- 通过扩展UIImageView的分类,在分类方法中实现多图下载功能,只给外部使用者暴露一个简单地网络接口
包含分类头文件UIImageView+WebCache.h
图片下载功能的实现
方法一
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
/**
url:图片的地址
placeholder:占位图片
*/方法二
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock
/**
progressBlock:下载过程中的回调Block,可以在该Block中计算下载进度
completedBlock:下载完毕的回调方法
*/
OC - 20.多图下载的更多相关文章
- iOS多线程-05-多图下载
效果图 常见问题及解决方法 图片重复下载 将内存保存在内存或沙盒中. 若下载的图片量较大,则会出现UI界面不流畅的现象 在子线程中执行下载操作,然后回到主线程成中进行UI界面的刷新. 由于cell的循 ...
- thinkPHP框架5.0 类图下载
thinkPHP5.0 类图下载
- 详解iOS多图下载的缓存机制
1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出 ...
- ios开发多线程四:NSOperation多图下载综合案例
#import "ViewController.h" #import "XMGAPP.h" @interface ViewController () /** t ...
- iconfont.cn阿里巴巴矢量图下载字体图标实战
1.阿里巴巴矢量图网址:www.iconfont.cn 2.然后用新浪微博账号登录 3.输入要查找的图标相应的关键字,回车 4.滑过要找的图标,点击购物车,让图标存储到暂存架中 5.点击暂存架,存储为 ...
- JS生成gif动态图下载
需求:通过动态变化的图生成一个gif图提供下载. 实现方案:1.可通过服务端生成对应gif,然后前端请求下载2.前端自己实现生成gif图片,自行下载 采用方案:前端实现方式,于是在网上找各种相关的几款 ...
- 2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景
作者:小林coding 计算机八股文网(操作系统.计算机网络.计算机组成.MySQL.Redis):https://xiaolincoding.com 大家好,我是小林. 我们都知道 Redis 提供 ...
- OC - GCD 队列组 - 下载图片画图
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ [self downloadIma ...
- OC 思维导向图
iOS 扩展思维导向图,如下图所示:
随机推荐
- MIT教授将网页开发整合为完整独立的程式语言Ur/Web
MIT 的软体技术教授 Adam Chlipala 设计了新的 Ur/Web 程式语言,这是一个整合 HTML.CSS.XML.SQL 及 JavaScript 等网路标准的“完整独立”语言,强调快速 ...
- Biathlon Track
Codeforces Round #242 (Div. 2) D:http://codeforces.com/contest/424/problem/D 题意:给你一个n*m的矩阵,每个格子上面有个数 ...
- bzoj1146
这是一道无比繁琐的题目话说这道题使我第一次练dfs序,比较感动:首先dfs序就是在dfs过程中按照访问的顺序给每个点标上两个“时间戳”一个是第一次访问到点i时的时间戳c[i],一个是访问完以i为根时的 ...
- BZOJ 1030 [JSOI2007]文本生成器
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2624 Solved: 1087[Submit][Stat ...
- Java---计算机贷款支付额计算(用对话框实现)
本例演示如何编写程序来计算贷款支付问题. 下面是编写程序的步骤: 1.提示用户输入年利率.年数和贷款总额 2.利用年利率算出月利率 3.通过前面的公式计算月支付额. 4.计算总支付额,它是月支付额乘以 ...
- 暴力求解——Equivalent Strings
Submit Status Description Today on a lecture about strings Gerald learned a new definition of string ...
- wait和waitpid的使用和区别
昨天看到一则新闻,讲的是一个游戏开发大拿猝死去世的新闻,公司发了讣告,打算接下去给他爸爸妈妈每个月10000的赡养费,很是感慨,本来中国的游戏业和国外就差距大,天妒英才啊.真心想对那些游戏公司的领导说 ...
- OpenWrt简要刷机教程
准备工作 1. 下载openwrt中文固件到PC.(当然其他英文固件也可) 2 找到路由器的RST键. 3 找到路由器刷机口---姑且称之为“WAN口” 4. 关闭路由器的电源. 5. 将PC网口 ...
- Threading Module源码概述(一)
Python的Threading模块是建立在thread module基础上的一个模块,在threading模块中,暴露着许多thread模块的属性.比如threading._get_ident实际上 ...
- Timeout for tests
如果想把timeout太久的测试自动标记为失败,有两种方法: 1.在 @Test里加上 Timeout 参数 定义"timeout=1000“的话,如果超过1000 毫秒,failure会被 ...