web-dev-qa-db-ja.com

[UIImage imageNamed ...]と[UIImage imageWithData ...]の違いは?

ファイルシステムからアプリケーションに画像をロードしたい。これを行うには2つの簡単な方法があります。

[UIImage imageNamed:fullFileName]

または:

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
NSData *imageData = [NSData dataWithContentsOfFile:fileLocation];

[UIImage imageWithData:imageData];

コードがはるかに少ないため、最初のものが好きですが、画像がキャッシュされており、このメソッドがより多くのメモリを使用していると言う人がいますか?私は他のほとんどのフォーラムの人々を信頼していないので、ここで質問したいと思いましたが、実際的な違いはありますか?もしそうなら、どちらが「良い」ですか?

Object Allocationインストゥルメントを使用してアプリのプロファイリングを試みましたが、実際の違いはわかりませんが、iPhone自体ではなくシミュレーターでのみ試しました。

65
rustyshelf

画像で何をしているかによって異なります。 imageNamed:メソッドは画像をキャッシュしますが、多くの場合、それはメモリの使用に役立ちます。たとえば、画像を10回ロードしてテーブルビューのテキストとともに表示すると、UIImageは10個の個別のオブジェクトを割り当てる代わりに、その画像の単一の表現のみをメモリに保持します。一方、非常に大きな画像があり、それを再利用していない場合は、データオブジェクトから画像をロードして、完了時にメモリから確実に削除することをお勧めします。

巨大な画像がなければ、心配する必要はありません。問題(およびプリエンプティブに最適化する代わりにオブジェクトの割り当てを確認することに対する称賛)が表示されない限り、無視できるメモリの改善よりも少ないコード行を選択します。

91

IImageのAPIリファレンスは次のように述べています:

+(UIImage *)imageNamed:(NSString *)name

このメソッドは、システムキャッシュ内で指定された名前の画像オブジェクトを探し、そのオブジェクトが存在する場合はそれを返します。一致する画像オブジェクトがまだキャッシュにない場合、このメソッドは指定されたファイルから画像データをロードし、キャッシュしてから、結果のオブジェクトを返します。

+(UIImage *)imageWithContentsOfFile:(NSString *)path

このメソッドは画像オブジェクトをキャッシュしません。

そのため、同じIエレメント(UITableViewCellなど)を多く使用し、同じイメージ(多くの場合アイコン)を使用し、パフォーマンスのために、もちろん同じ画像を再利用したいので、他の用途のためにメモリを節約します。一般的に、再利用画像は、ユーザーが操作するui要素でよく使用されます多くの場合。したがって、再利用する価値があります。そのため、imageNamed methodを使用することを選択できます。

一方、アプリケーションでは、ボタン、ロゴビューなど、アプリのライフサイクル中にI要素が存在するため、これらのui要素で使用されるこれらの画像は、また、アプリのライフサイクル中に存在するため、これらの画像をキャッシュする必要があるかどうかを考慮しません。したがって、imageNamedメソッドを使用することを選択できます。


それどころか、アプリケーションでは、動的に作成されるI Elementsがしばしばあります。たとえば、アプリケーションは動的なbackgroundをサポートしているため、ユーザーは好きな背景を選択できます。そしてbackgroundは画像である場合があります。 background(多くの場合IImageViewを使用してユーザーが選択します。リストビューに名前を付けることができますMyBackgroundListView。したがって、ユーザーが背景imageMyBackgroundListViewは機能を終了しているため、破棄する必要があります。ユーザーが次に自分の背景を変更したいときは、再度MyBackgroundListViewを作成できます。 MyBackgroundListViewで使用されるimagesはキャッシュしないでください。そうしないと、アプリケーションのメモリが不足します。したがって、今回はimageWithContentsOfFileメソッドを使用する必要があります。

Appleのドキュメント ビューでの高解像度画面のサポート のように

高解像度画面のデバイスでは、imageNamed:imageWithContentsOfFile:、およびinitWithContentsOfFile:メソッドは、@ 2xで要求された画像のバージョンを自動的に検索しますその名前の修飾子。見つかった場合は、代わりにその画像をロードします。特定の画像の高解像度バージョンを提供しない場合、画像オブジェクトは引き続き標準解像度画像(存在する場合)をロードし、描画中にスケーリングします。

そのため、網膜スクリーンの問題に対する画像の検索パスが心配になります。 IOSはあなたがそれに対処するのに役立ちます。

私の下手な英語でごめんなさい。役に立つかもしれません。

10
monjer

私の経験では[UIImage imageNamed:]は、特にUITableViewsで使用された場合、劇的にパフォーマンスが向上します。

それはメモリだけでなく、imageのデコードでもあります。キャッシュする方がはるかに高速です。

10
Hunter

画像をキャッシュしたくない場合は、initWithContentsOfFileを直接使用することもできます。

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
UIImage* yourImage = [[[UIImage alloc] initWithContentsOfFile:imagePath] autorelease];
7
CedricSoubrie

[UIImage imageNamed:]はキャッシングが少し多すぎるため、画像はあまりリリースされません。私はそれを使うことに注意するように言われました。

5
Ben Gottlieb

imageWithDataは、画像バイナリをデータベースに保存する場合、またはWebから大きな画像を徐々にダウンロードする場合に役立ちます。

3
Dan

アプリに同じではない大きな画像がたくさんある場合は、imagenamedを使用しません。使いすぎるとアプリがクラッシュしました。

0
user281300