『导言』
iOS开发中,如何保证图片只被下载一次?如何缓存图片?
内存缓存
?磁盘缓存
?到底如何区别?如何联系?
- 温馨提示:
(本文
理解思路
,代码可以不需掌握
,可以用第三方SDWebImage代替!)
- 个人理解:
1 、可以用内存缓存和磁盘缓存联合使用,保证只被下载一次。
2 、内存缓存:比如存入数据model中,具有临时性,当程序app重启,或者杀掉重启数据重现功能消失。
3 、磁盘缓存:比如存入沙盒的Caches中,平时也叫沙盒缓存。比如图片以NSdata形式存入。当程序重启或者杀掉重启数据保持。
- 表格
缓存 | 存入 | 特性 | 存图片格式 | 比如 |
---|---|---|---|---|
内存缓存 | model | 临时性 | UIImage |
上下 拖动cell数据显示,保证图片只下载一次,其他时候用内存/沙盒缓中数据 |
磁盘缓存 | 沙盒Caches | 持久性 | NSdata | APP最小化 /杀掉 后打开数据显示; 注意:app卸载 后沙盒缓存消失。 |
一、案例:
例如从plist文件读取标题子、标题、图片。图片如何保证下载一次?如何缓存数据?demo下载
- 步骤分析:
1 、内存缓存Model中是否有image
1- 1 如果有,显示图片
1-2 如果没有,看是否有沙盒缓存Caches
1-2-1如果有,存入内存缓存Model,并显示图片
1-2-2如果没有,下载图片,存image到Model,存NSdata到沙盒缓存Caches
![图.沙盒文件/路径](http://upload-images.jianshu.io/upload_images/2707674-5d9d3339e20933ab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 代码
#import "ViewController.h"
#import "ZWJModel.h"
@interface ViewController ()
@property (nonatomic,strong) NSArray *arrs;
//内存缓存--必须用可变字典
@property (nonatomic,strong) NSMutableDictionary *imageDics;
@end
@implementation ViewController
-(NSMutableDictionary *)_imageDics
{
if (_imageDics == nil) {
_imageDics = [[NSMutableDictionary alloc] init];
}
return _imageDics;
}
-(NSArray *)arrs
{
if (_arrs == nil) {
//arr 本地plist拿到
NSArray *arr= [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]];
//dic
NSMutableArray *arrM = [[NSMutableArray alloc] init];
for (NSDictionary * dic in arr) {
[arrM addObject:[ZWJModel arrMWithDic:dic]];;
}
// 转model
//model-arr
_arrs = arrM;
}
return _arrs;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.arrs count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID= @"cellID";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:cellID];
ZWJModel *model = [self.arrs objectAtIndex:indexPath.row];
cell.textLabel.text = model.name;
cell.detailTextLabel.text = model.download;
UIImage *image = [self._imageDics objectForKey:model.icon];
//-1-检查内存缓存是否有图片?
// -2 -如果有
if (image) {
cell.imageView.image = image;
NSLog(@"%zd 处的图片使用了内存中的图片",indexPath.row);
}
// -2-如果 没有-
else
{
//保存到沙河缓存
NSString *caches= [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];//文件夹路径
//获得图片名称,不能包含/ "http://p19.qhimg.com/dr/48_48_/t0164ad383c622aabef.png"
NSString *fileName = [model.icon lastPathComponent];
//拼接图片的全路径
NSString *fullPath = [caches stringByAppendingPathComponent:fileName];
//-3-检查磁盘/沙盒缓存
//-3-1 磁盘/沙盒缓存-有Yes
NSData *imageDataa =[NSData dataWithContentsOfFile:fullPath];
if (imageDataa) {
UIImage *image = [UIImage imageWithData:imageDataa ];
cell.imageView.image = image;
//-3-1-1保存到内存缓存
[self.imageDics setObject:image forKey:model.icon];
NSLog(@"沙盒缓存 ---%zd",indexPath.row);
}
//-3-2磁盘/沙盒缓存-没有No
else
{
//download下载图片-存入内存缓存model-存入沙盒缓存Caches
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:model.icon]];
UIImage *image = [UIImage imageWithData:imageData ];
cell.imageView.image = image;
//问题:UI和不良流畅---->开启子线程
//图片重复下载:-----》先把之前已经下载的图片保存起来(dic)
[self.imageDics setObject:image forKey:model.icon];
[imageData writeToFile:fullPath atomically:YES];
NSLog(@"%zd ---下载= ",indexPath.row);
}
}
return cell;
}
- 注释:缓存加强版demo
-
思路图:
-