我知道 -imageNamed: 方法返回一个缓存的 UIImage,但问题是我的图像文件存储在“文档”中,而 -imageNamed: 方法似乎只搜索 Bundle ...我目前(不情愿地)使用-imageWithContentsOfFile:从“文档”中获取我的图像,但它不一样......放大/缩小包含结果图像的 UIImageView 是不稳定和尴尬的。缩放包含使用 -imageNamed: 创建的图像的相同 UIImageView 但是看起来非常平滑。所以,再次:如果我不能使用 -imageNamed:,如何从我的“文档”中获取缓存的 UIImage?
4 回答
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
最简单的方法是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
子类和更复杂的缓存机制来解决这个问题。
您可以像缓存UIImages
一样缓存自己-imageNamed:
。它只是加载它们,然后抓住它们。您也可以使用NSDictionary
并实现您自己的-imageNamed:
但我更担心你在扩展时遇到的麻烦。你的图像是如何进入 Documents 的,你是如何缩放它们的,你是否测试过存储在包中的同一个图像文件?我怀疑这-imageNamed:
与此有关。我会更怀疑诸如捆绑应用了一些压缩的事实(尽管我还没有关于为什么这在实践中很重要的理论)、文件的差异或程序其余部分的差异缩放期间的行为(导致磁盘或 CPU 争用)。缓存不太可能与此问题相关。
我会使用 Instruments 进行一些分析,以尝试找出波动的来源。您是否正在使用磁盘、CPU、内存?瓶颈是什么?
编写自己的图像缓存怎么样?你已经准备好了所有的部分,现在你只需要封装它并记录你已经加载的图像。