tldr:ImagedNamedは問題ありません。メモリをうまく処理します。それを使用して、心配しないでください。
2012年11月の編集:この質問はiOS 2.0のものです。それ以来、画像の要件と処理は大きく変わりました。Retinaを使用すると、画像が大きくなり、読み込みが少し複雑になります。iPadおよびRetinaイメージの組み込みサポートにより、コードでImageNamedを使用する必要があります。さて、後世のために:
Apple Dev Forums の姉妹スレッドは、より良いトラフィックを受け取りました。具体的には、Rincewindが何らかの権限を追加しました。
iPhone OS 2.xには、メモリ警告の後でさえ、imageNamed:キャッシュがクリアされない問題があります。同時に、+ imageNamed:はキャッシュではなく、利便性のために多くの利用を得ています。これはおそらく、問題を本来よりもさらに拡大しているでしょう。
警告しながら
速度の面では、何が起こっているのかについての一般的な誤解があります。+ imageNamed:が行う最大のことは、ソースファイルから画像データをデコードすることです。これにより、ほとんどの場合、データサイズが大幅に増大します(たとえば、画面サイズのPNGファイルは、圧縮すると数十KBを消費する可能性がありますが、半分以上のMBを消費します)圧縮解除-幅*高さ* 4)。対照的に、+ imageWithContentsOfFile:は、画像データが必要になるたびにその画像を解凍します。ご想像のとおり、画像データが1度しか必要ない場合は、キャッシュされたバージョンの画像がぶら下がっていて、おそらく必要以上に長く続くことを除いて、ここでは何も勝ちません。ただし、頻繁に再描画する必要がある大きな画像がある場合は、代替手段がありますが、私が主に推奨するのは、その大きな画像の再描画を避けることです:)。
キャッシュの一般的な動作に関しては、ファイル名に基づいてキャッシュします(つまり、+ imageNamedの2つのインスタンスは同じ名前で同じキャッシュデータへの参照になるはずです)。 + imageNamed:。iPhone OS 2.xaのバグにより、メモリ警告を受け取ったときにキャッシュが縮小されるのを防ぎます。
そして
+ imageNamed:キャッシュはiPhone OS 3.0のメモリ警告を尊重する必要があると私は理解しています。機会があればテストし、そうでない場合はバグを報告してください。
だから、あなたはそれを持っています。imageNamed:ウィンドウを壊したり、子供を殺したりしません。とてもシンプルですが、最適化ツールです。悲しいことに、それはひどく名前が付けられており、使いやすいほどの等価性はありません-それゆえ人々はそれを使いすぎて、それが単にその仕事をすると怒る
これを修正するために、UIImageにカテゴリを追加しました。
// header omitted
// Before you waste time editing this, please remember that a semi colon at the end of a method definition is valid and a matter of style.
+ (UIImage*)imageFromMainBundleFile:(NSString*)aFileName; {
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", bundlePath,aFileName]];
}
Rincewindには、独自の最適化バージョンを構築するためのサンプルコードも含まれています。私はそれがmaintentaceの価値があるとは思いませんが、ここでそれは完全性のためです。
CGImageRef originalImage = uiImage.CGImage;
CFDataRef imageData = CGDataProviderCopyData(
CGImageGetDataProvider(originalImage));
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
CFRelease(imageData);
CGImageRef image = CGImageCreate(
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
CGImageGetBitsPerComponent(originalImage),
CGImageGetBitsPerPixel(originalImage),
CGImageGetBytesPerRow(originalImage),
CGImageGetColorSpace(originalImage),
CGImageGetBitmapInfo(originalImage),
imageDataProvider,
CGImageGetDecode(originalImage),
CGImageGetShouldInterpolate(originalImage),
CGImageGetRenderingIntent(originalImage));
CGDataProviderRelease(imageDataProvider);
UIImage *decompressedImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
このコードとのトレードオフは、デコードされた画像はより多くのメモリを使用しますが、レンダリングはより高速になることです。