1

J'appelle un service et renvoie un tas de latitudes et de longitudes que je place ensuite sur une carte en utilisant MapKit. En utilisant MKAnnotationView J'ajoute un RightCallOutButton à chaque annotation. J'ai donc dû créer un nouveau MapDelegate. Code ci-dessous.MKAnnotationView Le bouton RightCallOut bloque mon application quand je clique dessus

Si je clique sur le bouton, je crée l'application tombe en panne et j'obtiens une erreur de MonoTouch indiquant que le sélecteur accède à quelque chose qui a déjà été GC'd (ramasse-miettes). Donc, ma question serait, où devrais-je définir RightCalloutAccessoryView et où devrais-je créer le bouton, sinon dans ce code ci-dessous?

public class MapDelegage : MKMapViewDelegate { 

    protected string _annotationIdentifier = "BasicAnnotation"; 
    public override MKAnnotationView GetViewForAnnotation (MKMapView mapView,       NSObject annotation) { 

MKAnnotationView annotationView = mapView.DequeueReusableAnnotation(this._annotationIdentifier); 


if(annotationView == null) { 
    annotationView = new MKPinAnnotationView(annotation, this._annotationIdentifier); 
} else { 
    annotationView.Annotation = annotation; 
} 


annotationView.CanShowCallout = true; 
(annotationView as MKPinAnnotationView).AnimatesDrop = true;  
(annotationView as MKPinAnnotationView).PinColor = MKPinAnnotationColor.Green; 
annotationView.Selected = true;  
var button = UIButton.FromType(UIButtonType.DetailDisclosure); 
button.TouchUpInside += (sender, e) => { 
new UIAlertView("Testing", "Testing Message", null, "Close", null).Show(); 
} ; 

annotationView.RightCalloutAccessoryView = button; 
return annotationView; 
} 

} 

Répondre

1
annotationView = new MKPinAnnotationView(annotation, this._annotationIdentifier); 
... 
var button = UIButton.FromType(UIButtonType.DetailDisclosure); 

Vous devez éviter de déclarer des variables locales pour contenir des références que vous attendez à vivre plus longtemps la méthode elle-même. Une fois qu'il n'y a aucune référence à annotationView ou button le garbage collector (GC) est libre de les collecter (la partie gérée) même si c'est natives existe toujours. Cependant quand un rappel à eux est appelé, vous aurez un accident.

La solution la plus simple consiste à conserver une liste d'entre eux et (au niveau de la classe, c'est-à-dire un champ List<MKPinAnnotationView>) effacer la liste lorsque vous détruisez la vue. Le UIButton ne devrait pas être nécessaire puisqu'il y a une référence entre la vue et elle.

NOTE: travail est fait pour cacher cette complexité des développeurs dans les futures versions de MonoTouch. Malheureusement, vous ne pouvez pas ignorer ces problèmes pour le moment.

+0

alors je créerais une liste <> dans ma classe MapDelegate? Je ne sais pas ce que vous voulez dire par effacer la liste lorsque je détruis la vue. Où exactement est-ce que j'ajoute les PInAnnotations? Je pensais que GetViewForAnnotation juste manipulé une annotation à la fois? –

+0

D'accord, je pense que je comprends, et je l'ai eu à travailler. J'ai créé la liste et ajouté les annoationView à la liste. Dois-je m'inquiéter de la liste que j'ai créée ou sera-t-elle détruite par le GC à un moment donné? –

+0

Cela sera fait, par le GC, une fois qu'il n'y aura plus de référence à l'instance parent du champ, mais comme il pourrait grossir, vous feriez mieux de vous assurer que le 'parent' est Dispose'd dès que possible. Vous pouvez également l'effacer manuellement si vous masquez/affichez la vue (ou si vous la conservez en mémoire cache et ne l'effacez que lorsque vous recevez un avertissement de mémoire faible d'iOS). – poupou

Questions connexes