imageNamed:
私たちは皆、UIImage のメソッドの謎めいた舞台裏のキャッシュ メカニズムについて知っています。Apple のUIImage Class Referenceには、次のように書かれています。
メモリ不足の状況では、画像データを UIImage オブジェクトから削除して、システムのメモリを解放することができます。このパージ動作は、オブジェクト自体ではなく、UIImage オブジェクトによって内部的に保存された画像データのみに影響します。データが消去されたイメージを描画しようとすると、イメージ オブジェクトは元のファイルからデータを自動的に再読み込みします。ただし、この余分な負荷ステップにより、パフォーマンスがわずかに低下する可能性があります。
ただし、実際には、ドキュメントが示唆するように、画像データは「システムのメモリを解放するために UIImage オブジェクトから削除される」ことはありません。代わりに、アプリは「メモリ不足のために」終了するまでメモリ警告を受け取ります。
編集: Xcode プロジェクトで従来のイメージ ファイル参照を使用する場合、UIImage キャッシュは正常に機能します。メモリが解放されないのは、アセット カタログに移行するときだけです。
画像の長いリストをスクロールするために、いくつかの UIImageView を使用して UIScrollView を実装しました。スクロールすると、次の画像が読み込まれ、UIImageView のimage
プロパティに割り当てられ、以前に保持されていた UIImage への強力なリンクが削除されます。
のimageNamed:
キャッシュ メカニズムにより、すぐにメモリが不足し、約 170 MB のメモリが割り当てられた状態でアプリが終了します。
もちろんimageNamed:
、カテゴリ内のクラス メソッドをオーバーライドするなど、カスタム キャッシュ メカニズムを実装するための興味深いソリューションがたくさんあります。imageWithContentOfFile:
多くの場合、WWDC 2011 で Apple 開発者によって提案されたように、画像データをキャッシュしないクラス メソッドが代わりに使用されます。
これらのソリューションは、通常の画像ファイルでは問題なく機能しますが、パスとファイル拡張子を取得する必要がありますが、これは私が望むほどエレガントではありません。
ただし、Xcode 5 で導入された新しいアセット カタログを使用して、デバイスに応じて画像を条件付きで読み込むメカニズムと効率的な画像ファイル ストレージを利用しています。imageNamed:
今のところ、明らかな解決策がない限り、を使用せずにアセット カタログから画像をロードする簡単な方法はないようです。
アセット カタログを使用した UIImage キャッシング メカニズムは理解できましたか?
次のような UIImage のカテゴリを実装したいと思います。
static NSCache *_cache = nil;
@implementation UIImage (Caching)
+ (UIImage *)cachedImageNamed:(NSString *)name {
if (!_cache) _cache = [[NSCache alloc] init];
if (![_cache objectForKey:name]) {
UIImage *image = ???; // load image from Asset Catalog without internal caching mechanism
[_cache setObject:image forKey:name];
}
return [_cache objectForKey:name];
}
+ (void)emptyCache {
[_cache removeAllObjects];
}
@end
もちろん、アセット カタログを使用する場合のドキュメントに記載されているように、 の内部キャッシュをより詳細に制御しUIImage
、メモリ不足の状態で画像データをパージする可能性がある方法はさらに優れています。
読んでくれてありがとう。あなたのアイデアを楽しみにしています!