7

我知道 -imageNamed: 方法返回一个缓存的 UIImage,但问题是我的图像文件存储在“文档”中,而 -imageNamed: 方法似乎只搜索 Bundle ...我目前(不情愿地)使用-imageWithContentsOfFile:从“文档”中获取我的图像,但它不一样......放大/缩小包含结果图像的 UIImageView 是不稳定和尴尬的。缩放包含使用 -imageNamed: 创建的图像的相同 UIImageView 但是看起来非常平滑。所以,再次:如果我不能使用 -imageNamed:,如何从我的“文档”中获取缓存的 UIImage?

4

4 回答 4

9

I made an extension of the answer provided by rpetrich and overrode the imageName: method to add more of a drop in replacement. It searches the main bundle first and then looks in the caches directory. You could of course change the caches directory to the document directory.

@interface UIImage (CacheExtensions)
+ (UIImage *)imageNamed:(NSString *)name;
+ (void)clearCache;
@end

#import "UIImage+CacheExtensions.h"

static NSMutableDictionary *UIImageCache;

@implementation UIImage (CacheExtensions)

+ (UIImage *)imageNamed:(NSString *)name 
{
    id result;
    if (!UIImageCache)
        UIImageCache = [[NSMutableDictionary alloc] init];
    else {
        result = [UIImageCache objectForKey:name];
        if (result) return result;
    }

    // First, check the main bundle for the image
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:name ofType:nil];

    result = [UIImage imageWithContentsOfFileimagePath];
    if(result) {
        [UIImageCache setObject:result forKey:name];
        return result;
    }

    // If not found, search for the image in the caches directory
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *cachesImagePath = [[paths lastObject] stringByAppendingPathComponent:name];

    result = [UIImage imageWithContentsOfFile:cachesImagePath];
    if(result) {
        [UIImageCache setObject:result forKey:name];
        return result;
    }

    return nil;
}

+ (void)clearCache
{
    [UIImageCache removeAllObjects];
}

@end
于 2010-11-12T09:42:35.223 回答
8

最简单的方法是NSMutableDictionary存储缓存的图像和清除缓存方法:

@interface UIImage (CacheExtensions)
+ (id)cachedImageWithContentsOfFile:(NSString *)path;
+ (void)clearCache;
@end

static NSMutableDictionary *UIImageCache;

@implementation UIImage (CacheExtensions)
+ (id)cachedImageWithContentsOfFile:(NSString *)path
{
    id result;
    if (!UIImageCache)
        UIImageCache = [[NSMutableDictionary alloc] init];
    else {
        result = [UIImageCache objectForKey:path];
        if (result)
            return result;
    }
    result = [UIImage imageWithContentsOfFile:path];
    [UIImageCache setObject:result forKey:path];
    return result;
}
+ (void)clearCache
{
    [UIImageCache removeAllObjects];
}
@end

注意:您应该+[UIImage clearCache]从您的didReceiveMemoryWarning方法中调用。此外,clearCache将使缓存中的所有对象无效,而不仅仅是未使用的项目;需要一个UIImage子类和更复杂的缓存机制来解决这个问题。

于 2009-08-27T05:20:23.173 回答
4

您可以像缓存UIImages一样缓存自己-imageNamed:。它只是加载它们,然后抓住它们。您也可以使用NSDictionary并实现您自己的-imageNamed:

但我更担心你在扩展时遇到的麻烦。你的图像是如何进入 Documents 的,你是如何缩放它们的,你是否测试过存储在包中的同一个图像文件?我怀疑这-imageNamed:与此有关。我会更怀疑诸如捆绑应用了一些压缩的事实(尽管我还没有关于为什么这在实践中很重要的理论)、文件的差异或程序其余部分的差异缩放期间的行为(导致磁盘或 CPU 争用)。缓存不太可能与此问题相关。

我会使用 Instruments 进行一些分析,以尝试找出波动的来源。您是否正在使用磁盘、CPU、内存?瓶颈是什么?

于 2009-08-27T03:52:20.090 回答
1

编写自己的图像缓存怎么样?你已经准备好了所有的部分,现在你只需要封装它并记录你已经加载的图像。

于 2009-08-27T03:46:48.370 回答