美文网首页
图片缓存

图片缓存

作者: 闲得一B | 来源:发表于2016-05-02 20:16 被阅读99次
SDWebImage框架是为UIImageView添加的一个分类,提供了远程图片下载的缓存机制。
缓存机制大概的思路:
1、提供两个字典,一个字典中用将图片的URL作为Key图片作为value来保存,用来做内存缓存。还有一个字典将图片的URL作为Key下载图片的操作作为value。
2、首先根据URL去缓存中找是否有图片。
3、缓存中没有就去沙盒中查找是否有图片(根据URL的MD5生成唯一的图片名字)。
4、当沙盒中没有暂时设置占位图片。(设置占位图片的另一个原因是设置图片的尺寸)
5、发送请求,从网络中获取图片。
6、根据URL判断当前操作有没有正在下载。
7、没有下载,创建一个操作添加到队列中来异步下载图片,并将这个操作存放到字典中
8、下载失败,移除字典中的下载操作(防止下次不能下载),并返回。
9、下载成功,将图片放入缓存中。
10、回到主线程刷新`添加操作`这一行的cell(不直接设置图片的原因是防止循环利用显示出错)。
11、将图片写入沙盒(耗时操作尽量放到后面)。
12、移除操作。

#import <Foundation/Foundation.h>

@interface XDYBApp : NSObject
/** 图标 */
@property (nonatomic, strong) NSString *icon;
/** 下载量 */
@property (nonatomic, strong) NSString *download;
/** 名字 */
@property (nonatomic, strong) NSString *name;

+ (instancetype)appWithDict:(NSDictionary *)dict;
@end
#import "XDYBApp.h"

@implementation XDYBApp
+ (instancetype)appWithDict:(NSDictionary *)dict
{
    XDYBApp *app = [[self alloc] init];
    [app setValuesForKeysWithDictionary:dict];
    return app;
}
@end

#import "ViewController.h"
#import "XDYBApp.h"

@interface ViewController ()
/** 所有数据 */
@property (nonatomic, strong) NSArray *apps;

/** 内存缓存的图片 */
@property (nonatomic, strong) NSMutableDictionary *images;

/** 所有的操作对象 */
@property (nonatomic, strong) NSMutableDictionary *operations;

/** 队列对象 */
@property (nonatomic, strong) NSOperationQueue *queue;
@end

@implementation ViewController

- (NSOperationQueue *)queue
{
    if (!_queue) {
        _queue = [[NSOperationQueue alloc] init];
        _queue.maxConcurrentOperationCount = 3;
    }
    return _queue;
}

- (NSMutableDictionary *)operations
{
    if (!_operations) {
        _operations = [NSMutableDictionary dictionary];
    }
    return _operations;
}

- (NSMutableDictionary *)images
{
    if (!_images) {
        _images = [NSMutableDictionary dictionary];
    }
    return _images;
}

- (NSArray *)apps
{
    if (!_apps) {
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]];
        
        NSMutableArray *appArray = [NSMutableArray array];
        for (NSDictionary *dict in dictArray) {
            [appArray addObject:[XDYBApp appWithDict:dict]];
        }
        _apps = appArray;
    }
    return _apps;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    
    self.images = nil;
    self.operations = nil;
    [self.queue cancelAllOperations];
}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.apps.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"app";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    XDYBApp *app = self.apps[indexPath.row];
    cell.textLabel.text = app.name;
    cell.detailTextLabel.text = app.download;
    
    // 先从内存缓存中取出图片
    UIImage *image = self.images[app.icon];
    if (image) { // 内存中有图片
        cell.imageView.image = image;
    } else {  // 内存中没有图片
        // 获得Library/Caches文件夹
        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        // 获得文件名
        NSString *filename = [app.icon lastPathComponent];
        // 计算出文件的全路径
        NSString *file = [cachesPath stringByAppendingPathComponent:filename];
        // 加载沙盒的文件数据
        NSData *data = [NSData dataWithContentsOfFile:file];
        
        if (data) { // 直接利用沙盒中图片
            UIImage *image = [UIImage imageWithData:data];
            cell.imageView.image = image;
            // 存到字典中
            self.images[app.icon] = image;
        } else { // 下载图片
            cell.imageView.image = [UIImage imageNamed:@"placeholder"];
            
            NSOperation *operation = self.operations[app.icon];
            if (operation == nil) { // 这张图片暂时没有下载任务
                operation = [NSBlockOperation blockOperationWithBlock:^{
                    // 下载图片
                    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];
                    // 数据加载失败
                    if (data == nil) {
                        // 移除操作
                        [self.operations removeObjectForKey:app.icon];
                        return;
                    }
                    
                    UIImage *image = [UIImage imageWithData:data];
                    
                    // 存到字典中
                    self.images[app.icon] = image;
                    
                    // 回到主线程显示图片
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
                    }];
                    
                    // 将图片文件数据写入沙盒中
                    [data writeToFile:file atomically:YES];
                    // 移除操作
                    [self.operations removeObjectForKey:app.icon];
                }];
                
                // 添加到队列中
                [self.queue addOperation:operation];
                
                // 存放到字典中
                self.operations[app.icon] = operation;
            }
        }
    }
    
    return cell;
}

@end

相关文章

  • 架构&框架

    图片缓存 怎样设计一个图片缓存框架 图片管理者模块:内存缓存模块、磁盘缓存模块、网络图片下载模块 图片处理:图片解...

  • 区分SDWebImage的三种缓存

    SDWebImage的三种缓存分为:内存图片缓存、磁盘图片缓存、内存操作缓存步骤如下1、先查看内存图片缓存,内存图...

  • 多线程03

    SDWebImage框架详解 下载图片并显示: 下载图片/显示图片/内存缓存/磁盘缓存 下载图片\内存缓存\磁盘缓...

  • Android常用开源工具库

    一、图片缓存 Android-Universal-Image-Loader图片缓存,目前使用最广泛的图片缓存,支持...

  • iOS编程之缓存清除以及文件操作等

    1,SDWebImage图片缓存 这里简单讲解以下SDWebImage图片缓存大小计算以及清理缓存的方法 获取图片...

  • Kingfisher清理缓存功能

    我们使用开源项目Kingfisher来实现图片缓存功能。计算图片缓存和清理图片缓存也是通过Kingfisher来实...

  • SDImageCache

    SDImageCache提供了对图片的内存缓存、异步磁盘缓存、图片缓存查询等功能,下载过的图片会被缓存到内存,也可...

  • 6 单图缓存+刷新

    单张图片缓存思路先把图片缓存到本地,再获取图片大小 (GCD调度组监听下载完成) 单张图片缓存进入加载微博列表视图...

  • SDWebImage实现图片展示、缓存、清除缓存

    1.图片显示 2.图片缓存 3.检测缓存照片 4.清理图片缓存 5.下载路径与原理:

  • SDWebImage不缓存图片和不播放Gif

    不缓存图片问题: 使用SDWebImageManager的downloadImage函数下载图片时不缓存图片到沙盒...

网友评论

      本文标题:图片缓存

      本文链接:https://www.haomeiwen.com/subject/itulrttx.html