2009-08-27 7 views
7

私は-imageNamed:メソッドがCached UIImageを返すことを知っていますが、問題は私のイメージファイルが 'Documents'に格納されていて、-imageNamed:メソッドがバンドルのみを検索しているようです...私は現在)using -imageWithContentsOfFile: 'Documents'からイメージを取得するのに同じではありません...結果のイメージを含むUIImageViewの拡大/縮小は不安定で扱いにくいです。ただし、-imageNamed:で作成した画像を含む同じUIImageViewを拡大/縮小すると、非常に滑らかに見えます。だから、もう一度:-imageNamed:を使用できない場合、私はどのように私の 'Documents'からキャッシュされたUIImageを取得できますか?私の 'Documents'ディレクトリからCached UIImageを取得する方法はありますか?

答えて

4

UIImagesは、-imageNamed:のようにキャッシュできます。それは単にそれらをロードし、次にそれらを保持します。 NSDictionaryを使用してそれらを保持することもできますし、独自に実装することもできます。-imageNamed:

しかし、私はあなたがスケーリングに伴う問題をより心配しています。画像をどのようにして文書に変換し、どのように拡大縮小し、バンドルに保存されている同じ画像ファイルをテストしましたか? -imageNamed:にはこれと関係がないとは思わない。バンドルに圧縮が適用されているという事実(実際にはなぜこれが重要なのかについての理論はまだありませんが)、ファイルの違い、またはプログラムの残りの部分の違いスケーリング中に動作しています(ディスクまたはCPUの競合を引き起こします)。この問題に関連するキャッシュはほとんどありません。

私は、choppinessがどこから来ているかを調べるために、Instrumentsといくつかのプロファイリングを行います。あなたはディスク、CPU、メモリを最大限に活用していますか?ボトルネックは何ですか?

+0

hmmm ...興味深い..私はこれを今チェックし、あなたに戻ってきます。ありがとう – RexOnRoids

+0

私は問題を解決しましたが、私はまだ正確な原因が何か分かりません。スムーズにスケーリングされた画像はサイズが4kbで、偶数(2の累乗)を持ち、一般的なPNGファイルでしたが、サイズが200kb +、不均等なサイズのAdobe FireworksタイプのPNGファイルでした。ファイルサイズを減らし、次元を均等化し、ファイルタイプを変更したところ、スムーズにスケーリングが始まりました...理由を知っている人は – RexOnRoids

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 

注:あなたがdidReceiveMemoryWarning方法から+[UIImage clearCache]を呼び出す必要があります。また、clearCacheは、未使用アイテムだけでなく、キャッシュ内のすべてのオブジェクトを無効にします。 UIImageサブクラスとこれを修正するためにより複雑なキャッシングメカニズムが必要となります。

+0

ニース、シンプルなソリューションです。 +1 – iPadDeveloper2011

+0

間違いなく、ありがとう。 +1 –

9

私はrpetrichによって提供された答えを拡張して、imageName:メソッドをオーバーライドして、置き換えでより多くのドロップを追加しました。まずメインバンドルを検索してから、キャッシュディレクトリを探します。もちろん、キャッシュディレクトリをドキュメントディレクトリに変更することもできます。

@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 
+0

恐ろしい!これをうまく使います。 :) –

+1

カテゴリのメソッドを上書きしないでください。別の名前を使用してください。参照:http://stackoverflow.com/a/5272612/921573 –

+0

また、NSMutableDictionaryの代わりに 'NSCache'を使うことをお勧めします。それだけでそこにあります。 –

関連する問題