MKMapViewをプレイフィールドとして使用するiPhoneゲームに取り組んでいます。ほんの数分のプレイの後、アプリは必然的に遅くなり始め、メモリ不足のために最終的にクラッシュします。犯人を掘り下げた後、マップビューは常により多くのメモリを必要としているようです。このゲームでは、マップのズームとパンを頻繁に行う必要があるため、マップのタイルのキャッシュは、メモリがなくなるまで増え続けると推測できます。マップビューにタイルのキャッシュをフラッシュしたり、メモリ消費を抑制したりする方法はありますか?
3 に答える
* 注: この回答は、iOS 4.1 以前にのみ関連しています。この回答で説明されている問題は、iOS 4.2 でほとんど修正されています *
私のアプリはマップの両方を使用し、高い RAM を必要とする他の機能も備えているため、これについて掘り下げてきました。
答えは見つかりませんでしたが、回避策です。MKMapView のメモリ要求は、領域にズームインし、そのズームイン領域内でパンするにつれて指数関数的にエスカレートします。
MKMapView タイル キャッシュには 2 つのレベルがあります。1 つは Instruments の Malloc ~196kb として現れ、もう 1 つはさまざまなサイズの NSData (ストア) です。
Malloc はアクティブな使用中のタイルのようであり、割り当てることができる数には厳密な上限があります。私のアプリでは、その数は 16 ですが、UIView のサイズに基づいているかどうかはわかりません。これらの割り当ては厳密に管理されているようで、メモリ警告に応答します。
とにかく、特定のズーム レベル、たとえば大陸レベル (iPad の画面に北米の大部分を収めるのに十分なレベル) で、タイルのサイズを考えると、その第 2 レベルのキャッシュ (NSData (Store) ) を押してマップを完成させます。すべてがさわやかできれいです。大量の外部画像をアクティブ メモリに読み込むと、タイルが自動的にプルーニングされます。素晴らしい!
問題は、キャッシュの第 2 レベルに達したときに発生します。これは、ズームインしたときに発生し、16 個のタイルで平面全体を表示するのではなく、ロサンゼルスを表示するためだけに 16 個のタイルが必要になり、それらの古いタイルをダンプするだけでなく、それらを NSData (ストア) 決して解放されないように見える割り当て。
この NSData (ストア) は、デフォルトでメモリ内にのみ存在する NSURLConnectionCache です。このキャッシュにアクセスして制限することはできません。これはデフォルトの共有キャッシュではないためです (既に試しています)。
だから、ここで行き詰まる。
不満足な答えは、マップのズームを無効にしてかなり広いズームレベルで修正すると、この問題を完全に回避できるということですが、明らかに一部のアプリではこれが必要です...そしてそれは私が得た限りです.
私は Apple にサポート チケットを提出し、マップのこのばかげたキャッシュを制限する方法を明らかにできるかどうかを確認しました (ちなみに、アクティブ メモリに割り当てられた 50 MB 以上の RAM をさりげなく増やすことができました)。
お役に立てれば。
編集
次の iOS リリースでは、この無制限のキャッシュの問題が解決されたようです。MKMapView は、キャッシュされたタイル データを積極的に削除するようになりました。喜ぶ!
注釈ビューに再利用識別子を設定していますか? (これは、システムがこれらのビューをデタッチし、一度に少数のビューのみをメモリに保持できることを意味します。スクロールはデタッチされたビューを再利用するため、スクロールのパフォーマンスも向上します。)
このメソッドを使用して、再利用する注釈ビューを取得します。
- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier
マップキットだけでビュー サイズが 768x1024 (iPad サイズ) のアプリを作成すると、Instruments Allocations プログラムで報告されているように、アプリは 30 MB 以上の "Live Bytes" を簡単に消費する可能性があります。これは、iPad iOS v3.2.2 (来週までの最新バージョンは 4.2 リリースと想定) で実行されていることがわかりました。私の調査によると、この量のメモリは 1 つのアプリに対して大量にあるようです。ほとんどの開発者は、15 ~ 25 MB あたりでレベル 1 のメモリ警告を受け取り、そのレベルの直後にクラッシュすると報告しています。