iPad 3でメモリ不足のクラッシュが発生しました。これは、次のシナリオで追跡したものです。
CATiledLayerを使用してコンテンツ(PDFなど)を描画するUIViewには、独自のdrawRectメソッド(検索結果を強調表示するなど)を持つサブビューがあります。これにより、Core Animationは大量のメモリ(VMTracker機器では100MB以上)を消費し、簡単にクラッシュする可能性があります。この問題はすべてのデバイスに存在しますが、iPadのRetinaディスプレイでのみ、キャッシュサイズが大きくなりすぎます。
これは、AppleのPhotoScrollerの例で再現できます。UIViewをサブクラス化し、drawRectのコメントを解除し、TilingViewにインスタンスを追加します。アプリはiPad3でクラッシュします。drawRectにコメントすると、メモリ使用量が解決されます。
これで、サブビューを削除して、一番上のUIViewで描画を行うことができます。ただし、サブビューの操作は便利です(PDFの上に異なる独立したレイヤーを表すため)。2つの質問:
- 良い回避策は何ですか?できれば、複数のビューで作業を継続できるものが望ましいです。
- なぜこれが起こっているのですか?キャッシュメカニズムは時間外に機能していると思いますが、その背後にある技術的な詳細を理解することは素晴らしいことです。
ありがとう!
編集:
甲斐さんの答えを詳しく説明したいと思います。この問題は実際にはCATiledLayerとは関係ありませんでしたが、drawRectを実装したUIViewの使用法とは関係ありませんでした。
PhotoScrollerの場合、画像のサイズ(2000x2000以上)のUIViewを作成しました。これにより、drawRectが存在する場合に巨大なバッキングストアが作成されます。
私たちのアプリの場合、オーバーレイビューはフルスクリーン(iPad3では約11MB)であり、ページごとに約5つあります。スクロール中は最大3ページのメモリを保持します。つまり、150MBを超えるメモリが追加されます。楽しくない。
したがって、解決策は、drawRectを最適化するか、そのようなビューの使用を減らすことです。製図板に戻ると:-)