MKMapView Laden aller auf einmal Beschriftungsansichten (einschließlich derjenigen, die außerhalb des aktuellen rect sind)

StackOverflow https://stackoverflow.com/questions/1262742

Frage

UPDATE

Es sieht aus wie dieses Problem in iOS 4.3 leise wird behoben. Bis zu diesem Punkt, dass der Abstand „weit genug“ für eine Anmerkung recycelt betrachtet wurde zu sein schien Hunderte von Meilen zu sein, auch wenn sie in sehr eng gezoomt. Wenn ich meine App mit dem iOS 4.3 SDK bauen, sind Anmerkungen basiert auf mehr Zumutbaren recycelt werden.


Hat jemand sonst laufen in dieses Problem? Hier ist der Code:

- (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;
    }

...

Sobald die Ansicht angezeigt wird, erhalte ich

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

und so weiter, für jede Annotation (~ 60) Ich habe hinzugefügt. Die Karte (richtig) zeigt nur die zwei Anmerkungen in der aktuellen rect. Ich bin die Region in viewDidLoad Einstellung:

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];

Der Protokolleintrag für die Region seines Satz wird auf die Konsole ausgegeben, bevor Beschriftungsansichten angefordert werden.

Das Problem hier ist, dass da alle von den Anmerkungen auf einmal angefordert werden, [mapView dequeueReusableAnnotationViewWithIdentifier] nichts tun, da es einzigartiger MKAnnotationViews für jede Anmerkung auf der Karte ist. Dies führt zu Gedächtnisproblemen für mich.

Ein mögliches Problem ist, dass diese Anmerkungen in einem ziemlich kleinen Raum (ca. 1 Meile Radius) gruppiert sind. Obwohl die Karte in ziemlich eng in viewDidLoad (Breite und Länge Delta .001) gezoomt wird, lädt es nach wie vor alle der Beschriftungsansichten auf einmal.

Danke ...

War es hilfreich?

Lösung

Was man erwarten würde, ist eine Art von „Clipping“ der Beschriftungsansichten auf Basis des aktuellen region der Karte angezeigt wird.

Das ist nicht die Art und Weise der dequeueReusableAnnotationViewWithIdentifier Selektor funktioniert.

Von der Dokumentation: Als Beschriftungsansichten Offscreen bewegen , die Kartenansicht um sie zu einer intern verwalteten Wiederverwendung Warteschlange bewegt. Als neue Anmerkungen Bildschirm bewegen, und der Code aufgefordert wird, eine entsprechende Anmerkungsansicht zur Verfügung zu stellen, sollten Sie immer versuchen, eine vorhandene Ansicht aus der Warteschlange entfernt, bevor eine neue erstellt.

So ist der wiederverwendbare Mechanismus macht nur Sinn, wenn Sie eine Sequenz wie aufrufen:

//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];

Sie Fall, so wie ich den Ausschnitt implementieren würde (nur die Anmerkung für die aktuell angezeigte Region anzuzeigen) ist:

  • einen Delegierten zu Ihrem mapView hinzufügen und die - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated Methode implementieren informiert werden, wenn die Region geändert hat
  • durchlaufen alle Ihre Objekte diejenigen zu erhalten, die diese Region passen
  • addAnnotations auf Ihre Karte nur für die Objekte (Sie eine Art Zusammenführung zwischen den zuvor angezeigten Anmerkungen umsetzen können und die neue oder einfach von Grund auf neu zu starten, entfernen Sie alle Anmerkungen, und legen Sie die neuen

Natürlich, wenn der Benutzer zoomt ziemlich viel und dass der Umfang der Region zu groß ist (zu viele Pins angezeigt werden), dann müssen Sie eine Entscheidung treffen: ich alle Anmerkungen Ansichten angezeigt (und das Risiko eingehen, dass die Anzeige auf der Karte nicht viel Informationen nicht geben) oder muss ich eine Nachricht an den Benutzer zu sagen gesetzt „vergrößern Pins zu bekommen“ oder was auch immer. Aber das ist eine andere Geschichte ...;)

Andere Tipps

Nicht sicher, ob dies helfen wird, aber Sie erwähnten Speicherprobleme aufgrund Belastung von ~ 60 Objekte. Gibt es eine Möglichkeit bedingt jedes Objekt zu laden, basierend auf der aktuellen Karte Region Zentrum und aktuelle Karten Region Spannweite?

//:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top