13

アップデート

この問題はiOS4.3で静かに修正されたようです。この時点まで、注釈をリサイクルするのに「十分に遠い」と見なされた距離は、非常に近くにズームインした場合でも、数百マイルのように見えました。iOS 4.3 SDKを使用してアプリをビルドすると、より妥当な制限に基づいてアノテーションがリサイクルされます。


他の誰かがこの問題に遭遇しましたか?コードは次のとおりです。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(WWMapAnnotation *)annotation {



// Only return an Annotation view for the placemarks. Ignore for the current location--the iPhone SDK will place a blue ball there.

NSLog(@"Request for annotation view");

if ([annotation isKindOfClass:[WWMapAnnotation class]]){



    MKPinAnnotationView *browse_map_annot_view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"BrowseMapAnnot"];



    if (!browse_map_annot_view) {
        browse_map_annot_view = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"BrowseMapAnnot"] autorelease];
        NSLog(@"Creating new annotation view");
    } else {
        NSLog(@"Recycling annotation view");
        browse_map_annot_view.annotation = annotation;
    }

..。

ビューが表示されるとすぐに、

2009-08-05 13:12:03.332 xxx[24308:20b] Request for annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Creating new annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Request for annotation view
2009-08-05 13:12:03.333 xxx[24308:20b] Creating new annotation view

そして、私が追加したすべての注釈(〜60)に対して、何度も繰り返します。マップは(正しく)現在の四角形の2つの注釈のみを表示します。viewDidLoadでリージョンを設定しています:

if (center_point.latitude == 0) {
    center_point.latitude = 35.785098;
    center_point.longitude = -78.669899;
}

if (map_span.latitudeDelta == 0) {
    map_span.latitudeDelta = .001;
    map_span.longitudeDelta = .001;
}

map_region.center = center_point;
map_region.span = map_span;

NSLog(@"Setting initial map center and region");

[browse_map_view setRegion:map_region animated:NO];

注釈ビューが要求される前に、設定されている領域のログエントリがコンソールに出力されます。

ここでの問題は、すべての注釈が一度に要求されているため、[mapView dequeueReusableAnnotationViewWithIdentifier]は何もしないことです。これは、マップ上のすべての注釈に一意のMKAnnotationViewsがあるためです。これは私にとって記憶の問題につながります。

考えられる問題の1つは、これらの注釈が非常に小さなスペース(半径約1マイル)にクラスター化されていることです。マップはviewDidLoad(緯度と経度のデルタ.001)でかなりタイトにズームインされますが、それでもすべての注釈ビューを一度にロードします。

ありがとう...

4

2 に答える 2

14

予想されるのは、現在regionのマップに表示されている注釈ビューのある種の「クリッピング」です。

これはdequeueReusableAnnotationViewWithIdentifierセレクターの動作方法ではありません。

ドキュメントから: 注釈ビューが画面外に移動すると、マップビューはそれらを内部で管理されている再利用キューに移動します。新しい注釈が画面上に移動し、対応する注釈ビューを提供するようにコードにプロンプ​​トが表示されると、新しいビューを作成する前に、常に既存のビューのキューを解除するようにしてください。

したがって、再利用可能なメカニズムは、次のようなシーケンスを呼び出す場合にのみ意味があります。

//this will create 1000 annotation views
[theMap addAnnotations:my1000annotations];
//this will move them offscreen (but some annotation views may be kept internally for further reuse)
[theMap removeAnnotatios:theMap.annotations];
//when adding back again some annotations onscreen, some of the previous annotation views will be reused.
[theMap addAnnotations:someNew400annotations];

あなたの場合、クリッピングを実装する方法(現在表示されている領域の注釈のみを表示するため)は次のとおりです。

  • mapViewにデリゲートを追加し- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated、リージョンが変更されたときに通知を受け取るメソッドを実装します
  • すべてのオブジェクトを反復処理して、この領域に一致するオブジェクトを取得します
  • それらのオブジェクトのみのマップに注釈を追加します(以前に表示された注釈と新しい注釈の間に一種のマージを実装するか、最初からやり直して、すべての注釈を削除し、新しい注釈を設定することができます

もちろん、ユーザーがかなりズームアウトし、領域の範囲が大きすぎる(表示するにはピンが多すぎる)場合は、決定を下す必要があります。すべての注釈ビューを表示しますか(リスクを冒します)地図上の表示には多くの情報が表示されないこと)、または「ズームインしてピンを取得する」などのメッセージをユーザーに設定しますか。しかし、これは別の話です...;)

于 2010-03-29T09:05:25.680 に答える
0

これが役立つかどうかはわかりませんが、最大60個のオブジェクトのロードによるメモリの問題について言及しました。現在のマップ領域の中心と現在のマップ領域のスパンに基づいて各オブジェクトを条件付きでロードする方法はありますか?

// :)

于 2009-10-12T15:34:57.550 に答える