【问题标题】:Is there a way to refresh the cache used by UIImage class?有没有办法刷新 UIImage 类使用的缓存?
【发布时间】:2016-04-19 22:17:36
【问题描述】:

在我的 iOS 应用程序中,我使用 +imageNamed: 方法来加载图像(在代码中的许多不同位置)。 在一种情况下,用户可能会更新(下载)新图像。 当我尝试加载新的时,由于缓存,它会显示旧的。 从“Is there a way to clear the cache used by UIImage class?”的问题中,我看到我必须使用-initWithContentsOfFile:的方法。

但这不会利用+imageNamed: 享受的缓存加速。我想要的只是“告诉”文件已更改的缓存,因此它需要“重新缓存”它。然后继续对新缓存的图像使用+imageNamed: 方法。

换句话说,我使用+imageNamed: 方法(比如说)10 次,我更改图像,我“告诉”缓存,然后我继续使用+imageNamed: 方法另一个(比如说)10 次。如果我将所有+imageNamed: 更改为-initWithContentsOfFile:,那么我将失去缓存优势。

有没有办法/技巧来做到这一点?

【问题讨论】:

  • P.S.请不要使用私有框架解决方案。我的 App 上 AppStore,所以我必须使用“官方”工具。
  • 您链接的问题已经回答了这个问题。为什么又发了一篇?
  • 为什么还是显示旧图?他们有相同的名字吗?
  • 是的。名字是一样的。我只是覆盖(旧)文件。
  • 你可以给它一个唯一的名称并删除旧文件吗?

标签: ios objective-c caching uiimage


【解决方案1】:

没有用于清除缓存的 API。如果您的应用不是针对应用商店的,您可以调用 private 方法:

[UIImage _flushSharedImageCache];

但是我不希望它靠近生产代码。

相反,我会在 UIImage 上创建一个类别并添加一个从文件名返回所需图像的方法。此名称将被存储,然后在下载新图像时更新。您将获得缓存的好处,而无需任何棘手的变通办法。

根据您项目的复杂性,简单的查找和替换不会花费太长时间。

虽然我现在质疑您的应用目前的工作方式,但 imageNamed 仅在您的应用程序包中查找文件,因此不适用于用户下载的图像。

【讨论】:

  • 好吧,如果您要使用私有方法,那么您不妨在UIImage 上使用_flushSharedImageCache 方法,来自这个答案:stackoverflow.com/a/23292184/2976878
  • 谢谢,我不知道,我会更新答案。
  • 那(“但是我不希望它靠近生产代码”)是我要求一个干净的解决方案的原因。我在链接问题中看到的那个... :-(
  • 除了重写代码之外,没有其他干净的解决方案。使用 originaluser2 的方法,因为这适用于下载的图像,而 imageNamed 则不行。 (您是否在实际设备上尝试过您的代码?)
【解决方案2】:

您可能只需要找出自己的缓存图像方式。

我建议使用带有静态NSMutableDictionaryUIImage 类别,可以保存您的缓存图像。然后在初始化 UIImage 时使用您的自定义缓存方法。

例如:

@interface UIImage (UIImageCache)

+(UIImage*) cachedImageFile:(NSString*)imageFile;
+(void) resetCacheForImageFile:(NSString*)imageFile;

@end

@implementation UIImage (UIImageCache)

static NSMutableDictionary* cachedImages;

+(UIImage*) cachedImageFile:(NSString*)imageFile {

    // Optional error checking
    NSAssert1([[NSFileManager defaultManager] fileExistsAtPath:imageFile], @"Warning! The image file %@ doesn't exist.", imageFile);

    if (!cachedImages) cachedImages = [NSMutableDictionary dictionary];

    UIImage* cachedImg = [cachedImages objectForKey:imageFile];
    if (cachedImg) return cachedImg; // Image is cached, return it

    else { // No cached image, create one
        UIImage* img = [UIImage imageWithContentsOfFile:imageFile]; // iOS won't auto-cache the image.
        [cachedImages setObject:img forKey:imageFile];
        return img;
    }

}


+(void) resetCacheForImageFile:(NSString*)imageFile {
    [cachedImages removeObjectForKey:imageFile];
}

@end

【讨论】:

  • 嗯...谢谢你...我正在寻找一些东西...“不那么侵入性”...(我的意思是如果我已经有了一个轮子,为什么要重新发明轮子... )。不过还是谢谢...
  • 好吧,我不确定您有多少选择... Apple 一直对其 SDK 的内部运作非常保护,因此如果不使用私有方法,您将无法通过 SDK 执行此操作。
  • :-( ...我正在寻找一种解决方法或方法来欺骗缓存以重新加载文件...(不会弄乱“SDK的内部工作”)
  • 好吧,即使你设法找到了重置 UIImage 缓存的技巧,也不能保证它在未来的 iOS 版本中仍然可用。这种方式更易于维护和透明。
【解决方案3】:

也许我只是迟到了...但是使用

+ (UIImage *)imageWithContentsOfFile:(NSString *

我摆脱了缓存问题。

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-31
    • 2016-03-23
    • 2018-07-09
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多