我知道-imageNamed:方法返回一个Cached UIImage,但问题是我的图像文件存储在'Documents'中,-imageNamed:方法似乎只搜索Bundle ...我目前(不情愿地)使用-imageWithContentsOfFile:从'Documents'获取我的图像,但它不一样...向上/向下缩放包含结果图像的UIImageView是不稳定和笨拙的。缩放包含使用-imageNamed创建的图像的相同UIImageView:然而显得非常流畅。所以,再次:如果我不能使用-imageNamed,如何从我的'Documents'中获取缓存的UIImage?
答案 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)
编写自己的图像缓存怎么样?你有所有的部分,现在你只需要封装它并记录你已经加载的图像。