当我点击它时,MKAnnotationView RightCallOut按钮会崩溃我的应用程序

时间:2011-11-02 14:35:28

标签: garbage-collection xamarin.ios mkmapview mkannotationview

我正在调用一项服务并返回一堆经度和经度,然后我使用MapKit将其放置在地图上。

使用MKAnnotationView我正在为每个注释添加一个RightCallOutButton。

所以我不得不创建一个新的MapDelegate。代码如下。

如果我点击按钮我创建应用程序崩溃,我从MonoTouch收到一个错误,说选择器已经收到了已经过GC的垃圾(垃圾收集)。

所以我的问题是,我应该在哪里设置RightCalloutAccessoryView,如果不在下面的代码中,我应该在哪里创建按钮?

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

}

1 个答案:

答案 0 :(得分:1)

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

您应该避免声明局部变量来保存您希望比方法本身更长的引用。一旦没有对annotationViewbutton的引用,垃圾收集器(GC)就可以自由地收集它们(被管理部分),即使它的 native 对应物仍然存在。但是当调用它们的回调时,你会崩溃。

最简单的解决方案是保留它们的列表,并且(在类级别,即List<MKPinAnnotationView>字段)在销毁视图时清除列表。 UIButton不应该是必需的,因为视图和它之间有引用。

注意:正在努力隐藏来自开发人员在未来版本的MonoTouch中的这种复杂性。可悲的是,你现在不能忽视这些问题。