1

CGLayer doc から引用するには:

Quartz は、CGLayer オブジェクトを含め、再利用されるすべてのオブジェクトをキャッシュします。

大きなページのメモリに問題があり、画面のオン/オフに基づいてビューが解放および再作成される単純なメカニズムを実装しようとしています。

簡単にするために、ネットワーク リクエストの結果として作成された一連の UIImage が配列のどこかに保存されているとします。次のように UIImageView を作成します。

anImage = [anArray objectAtIndex:0];
UIImageView* imgView = [[UIImageView alloc] initWithImage:anImage];
[mainView addSubview:imgView]; // Quartz eats memory for view after first draw
[imgView release];             // owned by mainView now
[...]                          // wait a bit for draw cycle
[imgView removeFromSuperview]; // memory doesn't go down

が画面外にimgView出ると、それはremovedFromSuperview解放されます。結構ですよね?いいえ、Quartz に存在する CGLayer はanImageまだ存在するため、削除されません。

どうすればこれを回避できますか? このシナリオでの唯一の方法は、Quartz の背後にまったく同じイメージを別のポインター アドレスで作成し、古いイメージを削除することです。これを行う唯一の方法は、イメージを「ディープ コピー」するか (UIImage は NSCoding を実装していません)、ネットワーク経由で再度要求することです (遅い)。

私が考えているのは、画像をデータベースにsqlliteし、ビューが画面に表示されるたびにそれらを再取得する必要があるということですが、これについて人々の考えを聞きたいです.

4

1 に答える 1

1

ここでは、imgView を 0 から 1 に増やします。

UIImageView* imgView = [[UIImageView alloc] initWithImage:anImage];

次の行で、mainView は参照カウントをインクリメントします。(今は2です)

[mainView addSubview:imgView]; // Quartz eats memory for view after first draw

ここで、imgView を解放すると、参照カウントが 1 に戻ります。

[imgView release]; // owned by mainView now

あなたのメモリの問題は anImage とは何の関係もないと思います。imgView がサブビューである限り、そのオブジェクトを画面に描画する必要があるため、そのオブジェクトを解放しません。

次の行が意味することは、プログラムで CGLayer に描画する場合、Quartz は描画したものをキャッシュして、同じものを常に再描画しないようにすることです。サブビューの追加とはあまり関係ありません。

Quartz は、CGLayer オブジェクトを含め、再利用されるすべてのオブジェクトをキャッシュします。

于 2009-07-30T20:17:28.243 に答える