iOS 【令人头疼的 SDWebImage 缓存问题】

关于 SDWebImage 的缓存问题,困扰了一些时间。下面就整理一下该问题的解决方案。

当我们加载的图片来源是网络,url 地址不变的时候,刷新缓存是很有必要的。这种情况取决于后台返回的 imageUrl 的形式,如果后台每次刷新 image 都是返回不同的 imageUrl,那么这个情况自然不会发生。但如果刷新 image 只是更改了 image,而并没有更新不同的 imageUrl,那么就需要我们在代码中做一些处理了。

首先必须要再 AppDelegate.m 中作一些适配:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // SDWebImage 缓存配置
    SDWebImageDownloader *imgDownloader = SDWebImageManager.sharedManager.imageDownloader;
    // 获取SDWebImage的下载对象,所有图片的下载都是此对象完成的 SDWebImageDownloader *imgDownloader = SDWebImageManager.sharedManager.imageDownloader;
    imgDownloader.headersFilter  = ^NSDictionary *(NSURL *url, NSDictionary *headers) {
        // 下载图片成功后的回调
        NSFileManager *fm = [[NSFileManager alloc] init];
        NSString *imgKey = [SDWebImageManager.sharedManager cacheKeyForURL:url];
        NSString *imgPath = [SDWebImageManager.sharedManager.imageCache defaultCachePathForKey:imgKey];
        // 获取当前路径图片服务端返回的请求头相关信息
        NSDictionary *fileAttr = [fm attributesOfItemAtPath:imgPath error:nil];
        NSMutableDictionary *mutableHeaders = [headers mutableCopy];
        NSDate *lastModifiedDate = nil;
        // 大于0则表示请求图片成功
        if (fileAttr.count > 0) {
            if (fileAttr.count > 0) {
                // 如果请求成功,则手机端取出服务端Last-Modified信息
                lastModifiedDate = (NSDate *)fileAttr[NSFileModificationDate];
            }
        }
        // 格式化Last-Modified
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
        formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
        formatter.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss z";
        NSString *lastModifiedStr = [formatter stringFromDate:lastModifiedDate];
        
        lastModifiedStr = lastModifiedStr.length > 0 ? lastModifiedStr : @"";
        
        // 设置SDWebImage的请求头If-Modified-Since
        [mutableHeaders setValue:lastModifiedStr forKey:@"If-Modified-Since"];
        return mutableHeaders;
    };
}

在具体的 imageView 的设置上我们要如下设置:

[imgView sd_setImageWithURL:imgUrl placeholderImage:self.placeholderImg options:SDWebImageRefreshCached];

注意  SDWebImageRefreshCached 参数。

另外还需要注意一点,后台更新了 imageUrl 对应的 image,即使是这样设置过,前端也不会正常的改变图片。容易被人忽略的就是要及时刷新 UIImageView 对应的 image,通常做法是重新设置一次 image 即可。

你可能感兴趣的:(iOS)