有没有办法从我的'Documents'目录中获取Cached UIImage?

时间:2009-08-27 03:39:51

标签: iphone caching uikit uiimage bundle

我知道-imageNamed:方法返回一个Cached UIImage,但问题是我的图像文件存储在'Documents'中,-imageNamed:方法似乎只搜索Bundle ...我目前(不情愿地)使用-imageWithContentsOfFile:从'Documents'获取我的图像,但它不一样...向上/向下缩放包含结果图像的UIImageView是不稳定和笨拙的。缩放包含使用-imageNamed创建的图像的相同UIImageView:然而显得非常流畅。所以,再次:如果我不能使用-imageNamed,如何从我的'Documents'中获取缓存的UIImage?

4 个答案:

答案 0 :(得分:9)

我对rpetrich提供的答案进行了扩展,并覆盖了imageName:方法以添加更多的替换。它首先搜索主包,然后查看缓存目录。您当然可以将caches目录更改为文档目录。

@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

答案 1 :(得分: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子类和更复杂的缓存机制来解决这个问题。

答案 2 :(得分:4)

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

但是我更担心你在扩展方面遇到的麻烦。您的图像如何进入文档,如何缩放它们,并测试存储在捆绑中的相同图像文件?我怀疑-imageNamed:与此有什么关系。我会更怀疑捆绑包有一些压缩的事实(虽然我还没有关于为什么这在实践中很重要的理论),文件的差异,或者其他程序的差异在缩放期间表现出来(导致磁盘或CPU上的争用)。缓存不太可能与此问题有关。

我会对乐器进行一些分析,试图找出波动的来源。你最大化磁盘,CPU,内存?什么是瓶颈?

答案 3 :(得分:1)

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