YYWebImage进入后台后再次进入前台刷新一遍的问题

前言

在业务开发中发现一个必现的现象,在使用YYWebImage替代SDWebimage后,某个页面因为每次进入后台然后再切回前台时都会重新刷新页面,导致每次从后台回前台都会先展示占位图,然后才展示缓存过的网络图,找了很长半天发现是YYWebImage的一个默认属性的问题

原因一:

shouldRemoveAllObjectsWhenEnteringBackground:该属性为YES时,当APP进入后台后会情况MemeryCache的缓存,而且YYImageCacheYYMemoryCache的默认设置都是YES

原因二:

要命的是于此同时,UIImageView+YYWebImage里取内存缓存里的图片时,使用了YYImageCacheTypeMemory策略,导致如果没有取到内存的图片就先设置placeHolder,这就会导致会闪烁一下
UIImageView+YYWebImage.m

- (void)yy_setImageWithURL:(NSURL *)imageURL
               placeholder:(UIImage *)placeholder
                   options:(YYWebImageOptions)options
                   manager:(YYWebImageManager *)manager
                  progress:(YYWebImageProgressBlock)progress
                 transform:(YYWebImageTransformBlock)transform
                completion:(YYWebImageCompletionBlock)completion {
....省略的代码...
// get the image from memory as quickly as possible
        UIImage *imageFromMemory = nil;
        if (manager.cache &&
            !(options & YYWebImageOptionUseNSURLCache) &&
            !(options & YYWebImageOptionRefreshImageCache)) {
            imageFromMemory = [manager.cache getImageForKey:[manager cacheKeyForURL:imageURL] withType:YYImageCacheTypeMemory];
        }
        if (imageFromMemory) {
            if (!(options & YYWebImageOptionAvoidSetImage)) {
                self.image = imageFromMemory;
            }
            if(completion) completion(imageFromMemory, imageURL, YYWebImageFromMemoryCacheFast, YYWebImageStageFinished, nil);
            return;
        }
....省略的代码...
}

解决方案

方案一、修改UIImageView+YYWebImage里的读取图片逻辑,将YYImageCacheTypeMemory替换成YYImageCacheTypeAll,但该方案会修改三方库,不是很建议

- (void)yy_setImageWithURL:(NSURL *)imageURL
               placeholder:(UIImage *)placeholder
                   options:(YYWebImageOptions)options
                   manager:(YYWebImageManager *)manager
                  progress:(YYWebImageProgressBlock)progress
                 transform:(YYWebImageTransformBlock)transform
                completion:(YYWebImageCompletionBlock)completion {
....省略的代码...
// get the image from memory as quickly as possible
        UIImage *imageFromMemory = nil;
        if (manager.cache &&
            !(options & YYWebImageOptionUseNSURLCache) &&
            !(options & YYWebImageOptionRefreshImageCache)) {
            imageFromMemory = [manager.cache getImageForKey:[manager cacheKeyForURL:imageURL] withType:YYImageCacheTypeAll];
        }
        if (imageFromMemory) {
            if (!(options & YYWebImageOptionAvoidSetImage)) {
                self.image = imageFromMemory;
            }
            if(completion) completion(imageFromMemory, imageURL, YYWebImageFromMemoryCacheFast, YYWebImageStageFinished, nil);
            return;
        }
....省略的代码...
}

方案二,在APP启动时设置YYWebImage不要在进入后台后清空内存缓存

// 设置YYWebImage不要在APP进入后台清空内存缓存,防止出现先显示占位图再显示正式图的问题
    YYImageCache.sharedCache.memoryCache.shouldRemoveAllObjectsWhenEnteringBackground = NO;