2

iPad 3でメモリ不足のクラッシュが発生しました。これは、次のシナリオで追跡したものです。

CATiledLayerを使用してコンテンツ(PDFなど)を描画するUIViewには、独自のdrawRectメソッド(検索結果を強調表示するなど)を持つサブビューがあります。これにより、Core Animationは大量のメモリ(VMTracker機器では100MB以上)を消費し、簡単にクラッシュする可能性があります。この問題はすべてのデバイスに存在しますが、iPadのRetinaディスプレイでのみ、キャッシュサイズが大きくなりすぎます。

これは、AppleのPhotoScrollerの例で再現できます。UIViewをサブクラス化し、drawRectのコメントを解除し、TilingViewにインスタンスを追加します。アプリはiPad3でクラッシュします。drawRectにコメントすると、メモリ使用量が解決されます。

これで、サブビューを削除して、一番上のUIViewで描画を行うことができます。ただし、サブビューの操作は便利です(PDFの上に異なる独立したレイヤーを表すため)。2つの質問:

  1. 良い回避策は何ですか?できれば、複数のビューで作業を継続できるものが望ましいです。
  2. なぜこれが起こっているのですか?キャッシュメカニズムは時間外に機能していると思いますが、その背後にある技術的な詳細を理解することは素晴らしいことです。

ありがとう!

編集:

甲斐さんの答えを詳しく説明したいと思います。この問題は実際にはCATiledLayerとは関係ありませんでしたが、drawRectを実装したUIViewの使用法とは関係ありませんでした。

PhotoScrollerの場合、画像のサイズ(2000x2000以上)のUIViewを作成しました。これにより、drawRectが存在する場合に巨大なバッキングストアが作成されます。

私たちのアプリの場合、オーバーレイビューはフルスクリーン(iPad3では約11MB)であり、ページごとに約5つあります。スクロール中は最大3ページのメモリを保持します。つまり、150MBを超えるメモリが追加されます。楽しくない。

したがって、解決策は、drawRectを最適化するか、そのようなビューの使用を減らすことです。製図板に戻ると:-)

4

2 に答える 2

2

2へ:サブクラスに実装drawRectし、UIViewそのクラスのインスタンスがたくさんある場合は常に、メモリ使用量が劇的に増加します。UIKit理由は、フレームワークが何をしているのか、何を描いているのかを認識していないため、ビュー/サブビューの処理(ズームやスクロールなど)の多くの最適化トリックがそのようなオブジェクトでは機能しないためです。したがって、網膜に関係なくdrawRect、特に多くのオブジェクトやサブビューのレイヤーがある場合は、実装を避けてください。

1.:あなたが試しているものを正確に把握できませんでしたが、PDFの上に追加のコンテンツを表示することもできるPDFビューアを実装しました。私はそれをすべて通常のUIView階層、画像などで行いましたが、それがあなたが得る唯一の信頼できる作業であると私は恐れています

于 2012-04-30T14:36:40.063 に答える
1

私の経験:

  1. CATiledLayerに基づくUIViewにサブビューを追加しないでください
  2. CATiledLayerにサブレイヤーを追加しないでください

残念ながら、それが唯一の実用的な答えのようです-Appleの実装は多くの異なる方法でひどく間違っています(パフォーマンスだけでなく-レンダリング自体が視覚的なアーティファクトのバグを示し始め、Appleのレンダリングコードの一部が奇妙になるなど)。

実際には、私は常にこれを行います:

UIView:ビュー+-CATiledLayer付きのUIView:tiledLayerView +-UIview:subViewsView

...そしてビューとサブビューを「subViewsView」に安全に追加します。正常に動作します。

于 2012-04-30T15:28:08.500 に答える