第03天多线程网络:(01):多图下载程序缓存处理
2017-04-20 00:00
477 查看
#####一、多图下载程序缓存处理
code
LYHAppModel
VC
>>> cell 加载网络图片 新手容易出现两个问题 /* 1.UI很不流畅 (因为放到主线程里面) ---> 开启子线程下载图片 2.图片被重复下载 ---> 先把之前已经下载的图片保存起来(字典) 内存缓存 ---> 磁盘缓存(保存到沙盒里面) Document : 会备份,不允许存放缓存数据(如果存放会直接拒绝上线) Library : 两个子目录 Caches : 缓存数据 (用来保存缓存数据的) Preferences : 偏好设置 (用来保存一些账号信息) tmp : 临时路径(随时会被删除) */ >>> 缓存图片获取的逻辑 先去内存缓存中,该图片是否存在,如果存在,那么就直接拿到用,否则去检查磁盘缓存 // 如果有磁盘缓存,那么保存一份到内存,设置图片,否则就直接下载
code
LYHAppModel
>>>.h #import <Foundation/Foundation.h> @interface LYHAppModel : NSObject /** app的名称 */ @property(nonatomic, strong) NSString *name; /** app的图标 */ @property(nonatomic, strong) NSString *icon; /** app的下载量 */ @property(nonatomic, strong) NSString *download; // 提供一个方法 用于 字典转模型 + (instancetype)LYHAppModelWithDict:(NSDictionary *)dict; @end >>>.m #import "LYHAppModel.h" @implementation LYHAppModel + (instancetype)LYHAppModelWithDict:(NSDictionary *)dict { LYHAppModel *model = [[LYHAppModel alloc]init]; #pragma 字典转模型 几种方式 #pragma mark 1.一个一个转 //model.name = dict["name"]; #pragma mark 2.KVC [model setValuesForKeysWithDictionary:dict]; return model; } @end
VC
#import "ViewController.h" #import "LYHAppModel.h" @interface ViewController () /** 数组源 */ // 如何选择使用 可变还是不可变 是根据需求来说的 // 如果数据是固定的 那么就用 不可变的 // 如果数据是不固定 那么就用 可变的 @property(nonatomic, strong) NSArray *dataA; /** 内存缓存 */ // 每下载完一张图片 要保存起来 @property(nonatomic, strong) NSMutableDictionary *dict_images; @end @implementation ViewController - (NSMutableDictionary *)dict_images { if (_dict_images == nil) { _dict_images = [NSMutableDictionary dictionary]; } return _dict_images; } - (NSArray *)dataA { if (_dataA == nil) { // 字典数组 NSArray *arr = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil]]; NSLog(@"字典数组 -- arr %@",arr); // 字典数组 转成模型数字 // 1.先创建一个空的可变的数组 NSMutableArray *arrM = [NSMutableArray array]; // 2.遍历数组 for (NSDictionary *dict in arr) { // 3.将模型数据 添加到数组里面 [arrM addObject:[LYHAppModel LYHAppModelWithDict:dict]]; } // 4.执行完毕 arrM装满了模型 // 将arrM数组 赋值给 dataA (因为 arrM是一个临时的可变数组) _dataA = arrM; } return _dataA; } - (void)viewDidLoad { [super viewDidLoad]; // NSLog(@"%@",self.dataA); } #pragma mark --- --- #pragma mark tableViewDataScoure // 多少组 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } // 多少行 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataA.count; } // cell - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 1.创建cell static NSString *ID = @"app"; // 2.设置cell数据 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 拿到该行cell的数据 LYHAppModel *model = [self.dataA objectAtIndex:indexPath.row]; // 设置数据 // 2.1 设置标题 cell.textLabel.text = model.name; // 2.2 设置子标题 cell.detailTextLabel.text = model.download; // 2.3 设置图标 /* App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file. http 请求 需要修改plist文件 App Transport */ /* !! 这里有两个问题 : 1.UI很不流畅 (因为放到主线程里面) ---> 开启子线程下载图片 2. 图片被重复下载 ---> 先把之前已经下载的图片保存起来(字典) */ //2.4 先去内存缓存中,该图片是否存在,如果存在,那么就直接拿到用,否则去检查磁盘缓存 // 如果有磁盘缓存,那么保存一份到内存,设置图片,否则就直接下载 // 1)没有下载过 // 2)重新打开程序 (先去判断内存缓存有没有,没有再去磁盘缓存里面查找,找到了还需要保存到内存缓存里面) UIImage *image = [self.dict_images objectForKey:model.icon]; // 判断是否存在 if (image) { // 存在 直接使用 cell.imageView.image = image; NSLog(@"--%zd的图片使用内存缓存图片",indexPath.row); } else { // 2.保存到沙盒缓存 // 2.1 先获取沙盒缓存路径(文件路径) NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; // 2.2 获得图片的名称,不能包含/ NSString *fileName = [model.icon lastPathComponent]; // 获取文件的最后节点 // 2.3 拼接图片的全路径 NSString *fullPath = [caches stringByAppendingPathComponent:fileName]; NSLog(@" fullPath %@",fullPath); // 检查磁盘缓存(是否存在) NSData *imageData = [NSData dataWithContentsOfFile:fullPath]; if (imageData) { UIImage *image = [UIImage imageWithData:imageData]; cell.imageView.image = image; NSLog(@"--%zd的图片使用磁盘缓存图片",indexPath.row); // 1.把图片保存到内存缓存 [self.dict_images setObject:image forKey:model.icon]; } else { // 不存在 NSURL *url = [NSURL URLWithString:model.icon]; NSData *imageData = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:imageData]; cell.imageView.image = image; // 1.把图片保存到内存缓存 [self.dict_images setObject:image forKey:model.icon]; // 2.4 写数据到沙盒 (只能拿到imageData 写数据) /* 参数1 : 写到那个位置 参数2 : 表示原子性 */ [imageData writeToFile:fullPath atomically:YES]; NSLog(@"%zd--- ",indexPath.row); } } /** 参数1 : 目录 (NSCachesDirectory) 参数2 : 在主目录搜索 (NSUserDomainMask) 参数3 : 展开全路径 (YES) 获取的是一个数组 所以我们要获取一个元素 [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] /Users/liyuhong165/Library/Developer/CoreSimulator/Devices/3123A90B-7532-4EB3-B592-372608850556/data/Containers/Data/Application/3F311BAA-E974-443B-830B-54718DB7C6C1/Library/Caches 这里只是一个文件夹的路径 */ // NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] ); // 3.返回cell return cell; }
相关文章推荐
- 第03天多线程网络:(02):多图下载程序开子线程下载图片
- 第03天多线程网络:(03):多图下载程序完善
- 第03天多线程网络:(04):多图下载程序内存警告补充
- 第03天多线程网络:(11):多图下载程序应用NSCache
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(一)
- iOS基础8:自定义MyData/自定义SQLite用于网络判断,版本判断,图片缓存处理,下载或者上传的GET或POST请求,加密手段,.数据解析
- 为什么象网络蚂蚁这样的多线程程序可以加快下载速度?
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(四)
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(二)
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(三)
- Android ListView从网络获取图片及文字显示---图片缓存,多线程处理
- 多线程Java程序中常见错误的巧处理
- 用VB编写异步多线程下载程序
- 多线程图片下载程序的修改心得.
- j2me网络程序中移动资费页面的处理
- 多线程下载地图切片程序(更新)
- 一个简单的多线程、断点下载Java程序
- j2me网络程序中移动资费页面的处理
- WinSock实现多线程网络文件传输程序(一)(MFC+WinSock附源代码)
- Windows Forms 实现安全的多线程详解(附带程序代码示例) (摘自网络)