iOS 多线程编程<十三、NSOperation图片下载,SDWebImage底层实现原理>
2016-10-24 14:00
706 查看
NSOperation图片下载,SDWebImage底层实现原理
废话不多说,直接上代码:// // ViewController.m // DownLoadImage // // Created by fe on 2016/10/21. // Copyright © 2016年 fe. All rights reserved. // #import "ViewController.h" #import "DownloadModel.h" @interface ViewController () @property (nonatomic,strong) NSArray *sourceArray;//数据源数组 @property (nonatomic,strong) NSMutableDictionary *bufferMemonry;//图片内存缓存 @property (nonatomic,strong) NSOperationQueue *operationQueue;//下载图片的队列 @property (nonatomic,strong) NSMutableDictionary *operationMemonry;//操作缓存,避免重复添加操作 @end @implementation ViewController - (NSArray *)sourceArray { if (!_sourceArray) { NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"SourceList.plist" ofType:nil]; NSArray *dicArray = [NSArray arrayWithContentsOfFile:plistPath]; NSMutableArray *objectArray = [NSMutableArray array]; for (NSDictionary *dic in dicArray) { DownloadModel *sourceModel = [DownloadModel downloadModelWithDic:dic]; [objectArray addObject:sourceModel]; } _sourceArray = objectArray; } return _sourceArray; } - (NSOperationQueue *)operationQueue { if (!_operationQueue) { _operationQueue = [[NSOperationQueue alloc] init]; _operationQueue.maxConcurrentOperationCount = 5; } return _operationQueue; } //懒加载方式创建内存缓存字典 - (NSMutableDictionary *)bufferMemonry { if (!_bufferMemonry) { _bufferMemonry = [[NSMutableDictionary alloc] init]; } return _bufferMemonry; } - (NSMutableDictionary *)operationMemonry { if (!_operationMemonry) { _operationMemonry = [[NSMutableDictionary alloc] init]; } return _operationMemonry; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.sourceArray.count; } /* 要显示图片的时候,首先去内存中查看是否存在,如果存在,直接拿来用, 如果不存在,去沙河里面找,如果沙河里面存在,直接拿来用,并且保存一份到内存。 如果沙河里面不存在,下载图片,并且保存一份到内存,再保存一份到沙河。 */ /* Documents:存在该文件夹下的数据会备份,不能把下载的文件存放在该文件夹下, 如果把下载的文件存放在该文件夹下,苹果会拒绝你的产品上架 Library: cache:用于保存下载的文件 perference:存储偏好设置,和一些设备信息 tmp:临时文件夹 */ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *reuseIdentifier = @"downloadImage"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; DownloadModel *sourceModel = self.sourceArray[indexPath.row]; //先判断缓存中是否已经有这张图片 UIImage *image = [self.bufferMemonry objectForKey:sourceModel.icon]; if (image) { cell.imageView.image = [self.bufferMemonry objectForKey:sourceModel.icon]; }else//如果缓存中没有,去沙河中看看是否存在 { //获取cache路径 NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; //获取图片后缀名 NSString *imagePath = [sourceModel.icon lastPathComponent]; //拼接全路径 NSString *fullPath = [cache stringByAppendingPathComponent:imagePath]; NSData *data = [NSData dataWithContentsOfFile:fullPath]; UIImage *image =[UIImage imageWithData:data]; if (image) { cell.imageView.image = image; [self.bufferMemonry setObject:image forKey:sourceModel.icon]; }else//如果缓存和沙河中都没有,则从服务端下载图片 { //下载之前先判断操作队列里是否已经存在操作任务,如果不存在再添加任务 NSOperation *operation = self.operationMemonry[sourceModel.icon]; if (operation == nil) { NSBlockOperation *download = [NSBlockOperation blockOperationWithBlock:^{ NSURL *url = [NSURL URLWithString:sourceModel.icon]; NSData *imageData = [NSData dataWithContentsOfURL:url]; if (imageData == nil) { [self.operationMemonry removeObjectForKey:sourceModel.icon]; return ; } UIImage *image = [UIImage imageWithData:imageData]; //如果图片存在把图片写入缓存,保存到沙河 if (image) { [self.bufferMemonry setObject:image forKey:sourceModel.icon]; [imageData writeToFile:fullPath atomically:YES]; } //回到主线程刷新UI [[NSOperationQueue mainQueue] addOperationWithBlock:^{ //cell.imageView.image = image; //只刷新对应的行,提高tableview的性能 [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; }]; [self.operationMemonry removeObjectForKey:sourceModel.icon]; }]; [self.operationQueue addOperation:download]; [self.operationMemonry setObject:download forKey:sourceModel.icon]; } } } cell.textLabel.text = sourceModel.title; cell.detailTextLabel.text = sourceModel.subTitle; return cell; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
相关文章推荐
- iOS 多线程编程<十四、SDWebImage图片下载,内存警告处理>
- IOS-SDWebImage 底层实现原理以及面试题相关问题的学习链接
- 李洪强iOS开发之 - 实现九宫格并使用SDWebImage下载图片
- 关于SDWebImage中下载图片和缓存图片的实现原理
- iOS CATransition动画实现SDWebImage图片下载完成渐变动画
- iOS开发——多线程篇——快速生成沙盒目录的路径,多图片下载的原理、SDWebImage框架的简单介绍
- 使用SDWebImage实现图片下载的原理
- iOS-SDWebimage底层实现原理
- 多线程:实现下载图片(使用 SDwebImage框架)
- iOS网络编程(三) 异步加载及缓存图片---->SDWebImage
- iOS边练边学--多线程练习的多图片下载 以及 使用第三方框架(SDWebImage)的多图片下载
- iOS网络编程(三) 异步加载及缓存图片---->SDWebImage
- tableView异步下载图片/SDWebImage图片缓存原理
- SDWebImage底层实现原理
- iOS下载图片之SDWebImage的研究与使用
- iOS: (库) 图片异步下载/缓存-SDWebImage的使用
- iOS网络编程(三) 异步加载及缓存图片---->SDWebImage
- tableView异步下载图片/SDWebImage图片缓存原理
- IOS开发-第三方SDWebImage下载网络图片的使用
- AJ学IOS(55)多线程网络之图片下载框架之SDWebImage