-imageNamed:メソッドがキャッシュされたUIImageを返すことは知っていますが、問題は、画像ファイルが'Documents'に保存されており、-imageNamed:メソッドがバンドルのみを検索しているように見えることです...現在(しぶしぶ)使用しています-imageWithContentsOfFile:「ドキュメント」から画像を取得しますが、同じではありません...結果の画像を含むUIImageViewのスケールアップ/スケールダウンは途切れ途切れで扱いにくいです。ただし、-imageNamed:で作成された画像を含む同じUIImageViewのスケーリングは、非常にスムーズに表示されます。したがって、繰り返しますが、-imageNamedを使用できない場合、「ドキュメント」からキャッシュされたUIImageを取得するにはどうすればよいですか?
4 に答える
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
最も簡単な方法は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:
しかし、私はあなたがスケーリングで抱えている問題についてもっと心配しています。画像はどのようにドキュメントに取り込まれ、どのようにスケーリングされ、バンドルに保存されている同じ画像ファイルをテストしましたか?それがこれと関係があるので-imageNamed:
はないかと思います。バンドルに圧縮が適用されているという事実(これが実際に重要になる理由についての理論はまだありませんが)、ファイルの違い、またはプログラムの残りの部分の違いなどのことをもっと疑うでしょうスケーリング中に動作しています(ディスクまたはCPUで競合が発生しています)。キャッシングがこの問題に関連している可能性は低いです。
楽器を使ってプロファイリングを行い、途切れがどこから来ているのかを調べます。ディスク、CPU、メモリを使い果たしていますか?ボトルネックは何ですか?
独自の画像キャッシュを作成するのはどうですか?すべての要素が揃ったので、それをカプセル化して、すでにロードした画像の記録を保持する必要があります。