第03天多线程网络:(02):多图下载程序开子线程下载图片
2017-04-20 00:00
465 查看
#####一、多图下载程序开子线程下载图片
code
LYHAppModel
VC
>>> 开启子线程刷新UI NSBlockOperation *downloadOp = [NSBlockOperation blockOperationWithBlock:^{ ... 获取图片 .... 线程之间的通信 (UI刷新操作)[刷新tableview每行数据] }]; // 2.封装操作 // 3.添加操作到队列中 [self.queue addOperation:downloadOp]; >>> tableview不会主动刷新数据(我们手动刷新指定一行的数据) // [self.tableView reloadData]; 刷新整个tableview // 刷新某一行 /* 刷新的动画 UITableViewRowAnimationFade, UITableViewRowAnimationRight, // slide in from right (or out to right) UITableViewRowAnimationLeft, UITableViewRowAnimationTop, UITableViewRowAnimationBottom, UITableViewRowAnimationNone, // available in iOS 3.0 UITableViewRowAnimationMiddle, // available in iOS 3.2. attempts to keep cell centered in the space it will/did occupy UITableViewRowAnimationAutomatic = 100 // available in iOS 5.0. chooses an appropriate animation style for you */ [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; >>> 线程之间的通信(非主队列、主队列) // 线程之间的通信 [[NSOperationQueue mainQueue]addOperationWithBlock:^{ cell.imageView.image = image; }];
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; /** 队列(用来下载任务) */ @property(nonatomic, strong)NSOperationQueue *queue; @end @implementation ViewController #pragma mark 懒加载 - (NSOperationQueue *)queue { if (_queue == nil) { _queue = [[NSOperationQueue alloc]init]; // 在程序里面 最好只开3~5个队列 // 设置队列并发数 _queue.maxConcurrentOperationCount = 5; } return _queue; } - (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]]; NSMutableArray *arrM = [NSMutableArray array]; for (NSDictionary *dict in arr) { [arrM addObject:[LYHAppModel LYHAppModelWithDict:dict]]; } _dataA = arrM; } return _dataA; } - (void)viewDidLoad { [super viewDidLoad]; } #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]; // 设置数据 cell.textLabel.text = model.name; cell.detailTextLabel.text = model.download; //2.4 先去内存缓存中,该图片是否存在,如果存在,那么就直接拿到用,否则去检查磁盘缓存 // 如果有磁盘缓存,那么保存一份到内存,设置图片,否则就直接下载 // 1)没有下载过 // 2)重新打开程序 (先去判断内存缓存有没有,没有再去磁盘缓存里面查找,找到了还需要保存到内存缓存里面) UIImage *image = [self.dict_images objectForKey:model.icon]; if (image) { cell.imageView.image = image; NSLog(@"--%zd的图片使用内存缓存图片",indexPath.row); } else { NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *fileName = [model.icon lastPathComponent]; // 获取文件的最后节点 NSString *fullPath = [caches stringByAppendingPathComponent:fileName]; //NSLog(@" fullPath %@",fullPath); // 检查磁盘缓存(是否存在) NSData *imageData = [NSData dataWithContentsOfFile:fullPath]; // 废除磁盘缓存 imageData = nil; 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 { // 不存在 // NSOperationQueue *queue = [[NSOperationQueue alloc]init]; // 1.非主队列 NSBlockOperation *downloadOp = [NSBlockOperation blockOperationWithBlock:^{ NSURL *url = [NSURL URLWithString:model.icon]; NSData *imageData = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:imageData]; // NSLog(@"---download --%@",[NSThread currentThread]); #pragma UI刷新的操作 // 演示网速慢的情况 [NSThread sleepForTimeInterval:2.0]; // 线程之间的通信 [[NSOperationQueue mainQueue]addOperationWithBlock:^{ // [self.tableView reloadData]; 刷新整个tableview // 刷新某一行 /* 刷新的动画 UITableViewRowAnimationFade, UITableViewRowAnimationRight, // slide in from right (or out to right) UITableViewRowAnimationLeft, UITableViewRowAnimationTop, UITableViewRowAnimationBottom, UITableViewRowAnimationNone, // available in iOS 3.0 UITableViewRowAnimationMiddle, // available in iOS 3.2. attempts to keep cell centered in the space it will/did occupy UITableViewRowAnimationAutomatic = 100 // available in iOS 5.0. chooses an appropriate animation style for you */ [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; cell.imageView.image = image; // NSLog(@"---UI --%@",[NSThread currentThread]); }]; // 1.把图片保存到内存缓存 [self.dict_images setObject:image forKey:model.icon]; /* 参数1 : 写到那个位置 参数2 : 表示原子性 */ [imageData writeToFile:fullPath atomically:YES]; NSLog(@"%zd---下载-- ",indexPath.row); }]; // 2.封装操作 // 3.添加操作到队列中 [self.queue addOperation:downloadOp]; } } return cell; } /* 1.UI很不流畅 (因为放到主线程里面) ---> 开启子线程下载图片 2.图片被重复下载 ---> 先把之前已经下载的图片保存起来(字典) 内存缓存 ---> 磁盘缓存(保存到沙盒里面) 3.图片不会刷新(解决) 4.图片重复下载 5.数据错乱 */ @end
相关文章推荐
- iOS 开发 多线程详解之NSThread异步线程下载网络图片
- 第03天多线程网络:(03):多图下载程序完善
- 第03天多线程网络:(01):多图下载程序缓存处理
- 第03天多线程网络:(04):多图下载程序内存警告补充
- 第03天多线程网络:(11):多图下载程序应用NSCache
- 网络开始---多线程---NSThread-02-线程状态(了解)(三)
- AJ学IOS(51)多线程网络之GCD下载合并图片_队列组的使用
- java多线程下载网络图片
- 优雅设计封装基于Okhttp3的网络框架(三):多线程下载功能核心实现 及 线程池、队列机制、终止线程解析
- 猫猫学iOS(五十一)多线程网络之GCD下载合并图片_队列组的使用
- iOS-UIImageView加载网络下载的图片(异步+多线程)
- 猫猫学iOS(五十五)多线程网络之图片下载框架之SDWebImage
- iOS 网络与多线程--6.下载并保存网络图片
- 网络多线程-下载图片(不用SDWebImage框架)
- 网络下载图片 多线程 -复盘
- Android 多线程网络下载图片
- 使用线程下载网络图片
- Android--第四天(网络图片查看器,多线程下载,文件断点上传原理,Intent,Activity生命周期,广播,服务)
- AJ学IOS(55)多线程网络之图片下载框架之SDWebImage
- 多线程图片下载程序的修改心得.