图片缓存实现

在网络编程当中,如果我们能将向网络请求的图片缓存在本地当中,这将大大的提高我们重复加载图片的速度,使得用户体验更加的好。图片缓存的原理是以网络链接为原型,然后进行格式化的转换,形成一个新的名称,以这个名称作为图片缓存在本地的文件名(一般使用哈希算法,并且算法要保证几乎不会重复命名)。第二种方式是以字典保存链接,每一个链接对应字典的一个key,图片本身的名字作为value存在,那么在每一次请求图片数据的时候我们就能根据key值找到本地是否存在了缓存的图片名。本文中将使用第一种方式来实现缓存图片,其中只缓存20k大小以下的图片。

首先我使用的是MD5算法来对链接进行处理,最后生成一个新的文件名,MD5转换字符串代码如下:

- (NSString *)translateInMD5
{
    const char * originStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(originStr, (unsigned int)strlen(originStr), result);
    
    NSMutableString * outputStr = [NSMutableString stringWithCapacity: CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        
        [outputStr appendFormat: @"%02x", result[i]];
    }
    return outputStr;
}
MD5算法几乎可以保证我们不会生成同名文件,具体MD5实现大家可以百度查看。

图片的缓存方法以UIImageView类category的方式来实现,这样可以提高我们对代码的复用度。其中有两个方法,一个是返回缓存图片的绝对路径,另一个就是实现缓存方法。下面上代码:

实现缓存方法:

- (void)lxdSetImage:(NSString *)imageURL
{
    NSString * md5FileName = [imageURL translateInMD5];
    NSString * filePath = [self filePathOfCacheDirectoryWithFileName: md5FileName];
    NSData * imageData = [NSData dataWithContentsOfFile: filePath];
    if (imageData) {
        
        self.image = [UIImage imageWithData: imageData];
        return;
    }
    
    __weak typeof(self)weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       
        NSData * imageData = [NSData dataWithContentsOfURL: [NSURL URLWithString: imageURL]];
        //现将byte转换为bit(8:1)然后转换为kb(1024:1)
        CGFloat thousandBytes = imageData.length * 1.0 / (2 << 2) / (2 << 9);
        if (thousandBytes <= 20.0) {
            
            [imageData writeToFile: filePath atomically: YES];
        }
        weakSelf.image = [UIImage imageWithData: imageData];
    });
}

获取图片缓存绝对路径:

- (NSString *)filePathOfCacheDirectoryWithFileName: (NSString *)fileName
{
    NSString * documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    return [documentDirectory stringByAppendingPathComponent: [NSString stringWithFormat: @"cache/%@", fileName]];
}

我自定义的缓存方法暂时没有去考虑缓存图片的最大存在时间,我自身的想法包括两种方式来删除过期的缓存图片:

一、在每次缓存图片文件名生成之后,加上一个以当前时间为后缀的字符串,每次读取缓存图片之后异步检测缓存目录下所有图片的后缀名,超出最大保存时间的就使用NSFileManager删除这些文件

二、将缓存图片保存到sqlite中,添加一个当前时间的变量,每次获取缓存图片时同样查询所有缓存时间,超出最大保存时间就删除

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值