[解決済み] UIImage ImageNamedを払拭する。FUD
質問
2014年2月編集 この質問はiOS 2.0からのものであることに注意してください! 画像の要件と取り扱いは、それ以来大きく前進しています。Retinaは画像をより大きくし、読み込みも若干複雑になっています。iPadとRetina画像のためのビルトインサポートで。 あなたのコードでImageNamedを使用する必要があります。 .
多くの人が
imageNamed
が悪いと言う人が多いのですが、それと同じ数の人がパフォーマンスが良いと言っています。
UITableView
s. 参照
このSOの質問
を参照してください。
この記事
iPhoneDeveloperTips.comに掲載されています。
UIImage
's
imageNamed
メソッドは以前はリークしていたので避けるのが最善でしたが、最近のリリースで修正されました。私は、画像のキャッシュをシステムに任せていいところと、自分でやる必要があるところを合理的に判断するために、キャッシュ アルゴリズムをもっと理解したいと思います。私の現在の基本的な理解では、単純な
NSMutableDictionary
の
UIImages
はファイル名で参照される。大きくなり、メモリがなくなるとかなり小さくなります。
例えば、誰か確実に知っている人はいますか、画像キャッシュの後ろにある
imageNamed
に反応しないことを 知っている人はいますか?
didReceiveMemoryWarning
? Appleがこれをしないとは考えにくい。
キャッシュ アルゴリズムについて何かおわかりになることがあれば、ここに投稿してください。
どのように解決するのですか?
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 以上 (width * height * 4) を消費します)。これに対して、+imageWithContentsOfFile: は、画像データが必要になるたびに、その画像を解凍します。ご想像のとおり、画像データが一度しか必要ない場合は、キャッシュされたバージョンの画像がぶら下がるだけで、何も得るものはありませんし、おそらく必要以上の時間がかかるでしょう。しかし、頻繁に再描画する必要がある大きな画像がある場合、代替手段があります。)
キャッシュの一般的な動作に関しては、ファイル名に基づいてキャッシュされ (したがって、同じ名前を持つ 2 つの +imageNamed: インスタンスは、同じキャッシュ データへの参照となります)、+imageNamed: でさらに画像を要求すると、キャッシュは動的に大きくなります。iPhone OS 2.x では、メモリ警告を受信したときにキャッシュが縮小されないというバグがあります。
と
私の理解では、+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は、最適化されたバージョンを自分で作るためのサンプルコードも含んでいます。私はそれを維持する価値があるとは思えませんが、念のためここに載せておきます。
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);
このコードとのトレードオフは、デコードされた画像はより多くのメモリを使用しますが、レンダリングはより高速になるということです。
関連
-
[解決済み] Cocoapodsの使用時にXcodeの警告を無視する
-
[解決済み] アプリのプッシュ通知設定をリセットする
-
[解決済み] iPhone Safari ウェブアプリでリンクを新しいウィンドウで開く
-
[解決済み] iPhoneでMonoTouchは禁止になったのか?[クローズド]
-
[解決済み] 再署名 IPA (iPhone)
-
[解決済み] ナビゲーションコントローラスタック、サブビュー、モーダルコントローラを使用せずに、ビューコントローラの変化をアニメーション化する?
-
[解決済み] CALayer setNeedsDisplayInRect:] の暗黙のアニメーションを無効にする。
-
[解決済み] iPhone 5 CSSメディアクエリ
-
[解決済み] UITextFieldの高さを設定するには?
-
[解決済み] 現在のメソッド呼び出しのスレッド ID を取得する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] UILongPressGestureRecognizerが押し下げ時に2回呼び出される
-
[解決済み] CGFloatとfloatを使うことの違いは何ですか?
-
[解決済み] iPhoneでウェブページからアプリがインストールされているかどうかを確認する方法
-
[解決済み] iOSでHTMLをNSAttributedStringに変換する
-
[解決済み] レビュー待ちの状態でバイナリを拒否する(バイナリ拒否ボタンが見つからない)
-
[解決済み] iOSアプリでターゲットのバージョン/ビルド番号をプログラム的に表示するには?
-
[解決済み] モバイルアプリにおけるOAuthの秘密
-
[解決済み] position: iPadとiPhoneで固定が効かない。
-
[解決済み] Mac OS Xのスタティック・ライブラリ(.a)のターゲット・アーキテクチャはどのように決定するのですか?
-
[解決済み] UILabelがラベルサイズに合うようにテキストを自動縮小しない