一、简单介绍
最近在看SDWebImage的源码的时候发现了在- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key 方法中如果我们带有扩展名的key找不到图片的话,就去使用删除扩展名的key。关于此SDWebImage也有解释,给了个链接 https://github.com/rs/SDWebImage/issues/967以及https://github.com/rs/SDWebImage/pull/976
关于下面这个函数做了带有扩展名的key的图片的搜索以及不带扩展名的key的搜索,因为SDWebImage也要兼容旧的版本,旧的版本之前保存图片有没有带扩展名的(下面会有解释),所以下面做图片搜索的时候也包含进去了。做了一个兼容。
- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key {
//生成绝对路径
NSString *defaultPath = [self defaultCachePathForKey:key];
//data存在了就直接返回
NSData *data = [NSData dataWithContentsOfFile:defaultPath options:self.config.diskCacheReadingOptions error:nil];
if (data) {
return data;
}
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
// checking the key with and without the extension
//不存在就删除扩展名去寻找
data = [NSData dataWithContentsOfFile:defaultPath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil];
if (data) {
return data;
}
//还是没找到就去我们指定的路径中去寻找
NSArray<NSString *> *customPaths = [self.customPaths copy];
for (NSString *path in customPaths) {
NSString *filePath = [self cachePathForKey:key inPath:path];
NSData *imageData = [NSData dataWithContentsOfFile:filePath options:self.config.diskCacheReadingOptions error:nil];
if (imageData) {
return imageData;
}
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
// checking the key with and without the extension
imageData = [NSData dataWithContentsOfFile:filePath.stringByDeletingPathExtension options:self.config.diskCacheReadingOptions error:nil];
if (imageData) {
return imageData;
}
}
return nil;
}
通过这两个网页里面的内容我们就可以了解到之前SDWebImage版本是没有去检查扩展名是否存在,也没有去拼接上扩展名。这样就会引起如下所示的问题,下面的意思就是说,我展示了一个带有SDWebImage的图像的预览,我想在一个QLPreviewController中查看这个图像。我使用cachedFileNameForKey获得了磁盘上的文件名,但是不幸的是,cachedFileNameForKey选择了一个没有文件扩展名的文件名,而QLPreviewController还不够聪明。如果SDWebImage在MD5散列结束时从URL中保留了文件扩展名,那将非常方便。

所以之后SDwebImage关于扩展名的处理改成了这样
- (nullable NSString *)cachedFileNameForKey:(nullable NSString *)key {
const char *str = key.UTF8String;
if (str == NULL) {
str = "";
}
unsigned char r[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, (CC_LONG)strlen(str), r);
NSURL *keyURL = [NSURL URLWithString:key];
NSString *ext = keyURL ? keyURL.pathExtension : key.pathExtension;
NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@",
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10],
r[11], r[12], r[13], r[14], r[15], ext.length == 0 ? @"" : [NSString stringWithFormat:@".%@", ext]];
return filename;
}
所以上面其实为什么要删除扩展名来寻找,那是因为有些文件保存在磁盘当中可能是没有扩展名的,图片没有扩展名也是可以保存的。
关于pathExtension的概念,比如说我们有这么一个url
NSURL * url = [NSURL URLWithString:@"http://img.zcool.cn/community/012cb757939a8e0000018c1b7482be.jpg@1280w_1l_2o_100sh.png"];
NSLog(@"%@",url.pathExtension);
输出的是png