4

次の問題があります。

4x4 レイアウトで 16 の正方形 (それぞれが UIImageView から継承して作成したクラス) のグリッドを表示するプライマリ ビュー オブジェクト (UIView から継承) があります。

これらの 16 個の正方形はそれぞれ 160x160 で、30kb 以下の画像 (正方形ごとに異なる画像) が含まれています。ただし、画像は 500x500 (プログラムの他の場所でフルサイズで使用されるため) であるため、setFrame メソッドによって「正方形」クラスで 160x160 にサイズ変更されます。

アプリの実行中に Xcode のメモリ管理機能を調べると、いくつかのことに気付きました。

  1. これらの各正方形をプライマリ ビュー オブジェクトに追加すると、アプリのメモリ使用量が 1 MB 増加します。これはインスタンス化時には発生しませんが、プライマリ ビュー オブジェクトで [self addSubview:square] によって追加された場合にのみ発生します。
  2. すべての正方形に同じ画像を使用すると、メモリの増加は最小限になります。画像なしで正方形のオブジェクトを初期化すると、増加は基本的にゼロになります。
  3. 同じアプリをシミュレーターで実行すると、実際のデバイスの 1/6 のメモリが使用されます。

ここで要点は、30kb の画像をロードするときに、各正方形が 1MB のメモリを消費するのはなぜですか? これを減らす方法はありますか?[UIImage imageNamed:img][UIImage imageWithContentsFromFile:path][UIImage imageWithData:imgData scale:scale]、およびフレームのサイズを変更しないなど、さまざまな方法で画像を作成しようとしました。

4

1 に答える 1

5

小さい で 500x500 の画像を使用するとUIImageView、大きな画像がメモリに読み込まれます。UIImageこれを解決するには、 自体のサイズを変更し( の を調整するだけframeでなくUIImageView)、160x160 の画像を作成し、その画像をビューで使用します。画像のサイズを変更するコードについては、この回答を参照してください。これは、次のように呼び出すことができます。

UIImage *smallImage = [image scaleImageToSizeAspectFill:CGSizeMake(160, 160)];

サイズ変更された画像を保存したい場合もあります。そのため、毎回小さな画像を作成するという計算上のオーバーヘッドに常に悩まされることはありません。次に例を示します。

NSData *data = UIImagePNGRepresentation(smallImage);
[data writeToFile:path atomically:YES];

その後、ビューの今後の呼び出しで、小さな画像に対応するその PNG ファイルを読み込むことができます。


なぜそんなに多くのメモリを消費するのかという質問への答えとして、画像は圧縮されたJPGまたはPNGとして永続ストレージに保存されている可能性がありますが、圧縮されていないビットマップとしてメモリに保持されていると思われます。内部フォーマットは多数ありますが、一般的なのは、赤、緑、青、およびアルファがそれぞれ 8 ビットの 32 ビット フォーマットです。詳細に関係なく、1 ピクセルあたり 4 バイトの 500 x 500 ピクセル表現が 1 MB のメモリに変換される様子がすぐにわかります。ただし、160 x 160 の画像は、およそ 10 分の 1 のサイズにする必要があります。

于 2013-09-26T23:34:44.360 に答える