学习完SDWebImage第三方框架之后,根据它的流程,试着简写自定义下载图片的方法。
创建单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #pragma mark - 单例 static CHImageManager *_sharedInstance; + (CHImageManager *)sharedManager { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (!_sharedInstance) { _sharedInstance = [[CHImageManager alloc] init]; } }); return _sharedInstance; }
+ (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedInstance = [super allocWithZone:zone]; }); return _sharedInstance; }
- (instancetype)init { self = [super init]; if (self) { } return self; }
|
设置URL缓存过滤器并给出方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| //定义缓存过滤器的block块 typedef NSString *(^CHImageCacheKeyFilterBlock)(NSURL *url);
@property (nonatomic, copy) CHImageCacheKeyFilterBlock cacheKeyFilter; //缓存过滤器
#pragma mark - URL过滤器 //返回指定URL的缓存键值,就是URL字符串 - (NSString *)cacheKeyForURL:(NSURL *)url { //如果URL不存在,那么就返回空 if (!url) { return @""; }
//先判断是否设置了缓存过滤器,如果设置了则走cacheKeyFilterBlock,否则直接把URL转换为字符串之后返回 if (self.cacheKeyFilter) { return self.cacheKeyFilter(url); } else { return [url absoluteString]; } }
|
需要外部自己设置过滤规则 实现cacheKeyFilter相关
自定义下载方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| - (void)customImageView:(UIImageView *)imageView UrlStr:(NSURL *)urlStr{
//容错处理 if ([urlStr isKindOfClass:NSString.class]) { urlStr = [NSURL URLWithString:(NSString *)urlStr]; }
if (![urlStr isKindOfClass:NSURL.class]) { urlStr = nil; }
if (!urlStr) { return; }
// 缓存key NSString *cacheKey = [self cacheKeyForURL:urlStr];
/* 从内存缓存中取 */ UIImage *image = [self.imagesCache objectForKey:cacheKey]; if (image) { // 直接设置 imageView.image = image; }else{ /* 检查磁盘缓存 */ // 获取文件路径 NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; // 获取图片名称 获取节点 NSString *fileName = [cacheKey lastPathComponent]; // 拼接文件全路径 NSString *fullPath = [cachePath stringByAppendingPathComponent:fileName]; // 从磁盘缓存中取 NSData *data = [NSData dataWithContentsOfFile:fullPath];
if (data) { // 将二进制数据转成图片 UIImage *image = [UIImage imageWithData:data]; // 设置图片 imageView.image = image; // 把图片存到内存缓存中 [self.imagesCache setObject:image forKey:cacheKey]; }else{ /* 检查操作缓存 */ // 清空图片或者占位图片 imageView.image = nil; // 检查操作缓存 NSBlockOperation *downloadOperation = [self.operationsCache objectForKey:cacheKey]; if (downloadOperation) { // 不处理
}else{ downloadOperation = [NSBlockOperation blockOperationWithBlock:^{ // 下载图片三部曲 NSData *tempData = [NSData dataWithContentsOfURL:urlStr]; UIImage *tempImage = [UIImage imageWithData:tempData]; if (tempImage == nil) { // 移除操作缓存中的操作 [self.operationsCache removeObjectForKey:cacheKey]; return ; } // 把图片存到内存缓存 [self.imagesCache setObject:tempImage forKey:cacheKey];
// 把图片保存到磁盘缓存 dispatch_async(dispatch_get_global_queue(0, 0), ^{ [data writeToFile:fullPath atomically:YES]; });
// 回到主线程 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // 设置图片 //imageView.image = tempImage; // 刷新一行(会重新调用cellForRow方法) //[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
}]; }]; // 添加操作缓存 [self.operationsCache setObject:downloadOperation forKey:cacheKey]; // 将操作加入队列 [self.queue addOperation:downloadOperation]; } } } }
|
移除缓存策略
1 2 3 4 5 6 7 8 9
| #pragma mark - 清除缓存 - (void)cleanCache{ // 内存缓存 [self.imagesCache removeAllObjects]; // 操作缓存 [self.operationsCache removeAllObjects]; // 取消队列中的操作 [self.queue cancelAllOperations]; }
|
这里是具体实现方法 点击查看