Monotouch mapkit mkannotation集合会产生错误

时间:2013-04-03 22:29:11

标签: xamarin.ios mapkit mkannotation xamarin pins

Monotouch又名xamarin ios新手。试图获得一个可以使用多个引脚的强大的mapkit。尝试一个基本的例子,我从各种各样的资源中拼凑出来,我可以找到它。

发现零星的SIGSEGV错误。当单击引脚以显示有时有效且有时不起作用的警告框时,似乎会出现某种内存错误。

我不确定我哪里出错了。这是沿着正确的方向吗?这是代码

    using System;
    using System.Drawing;

    using MonoTouch.Foundation;
    using MonoTouch.UIKit;
    using MonoTouch.MapKit;
    using MonoTouch.CoreLocation;
    using System.Collections.Generic;

    namespace singleview
    {
    public partial class singleviewViewController : UIViewController
    {
        public singleviewViewController () : base ("singleviewViewController", null)
        {

        }

        private LocationService locationService;
        private MKMapView mapView;

        List<BasicMapAnnotation> pins = new List<BasicMapAnnotation>();

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // example of a series of map points
            pins.Add(new BasicMapAnnotation(new CLLocationCoordinate2D(37.766995, -122.419580), "h", "sub1", "id1"));
            pins.Add(new BasicMapAnnotation(new CLLocationCoordinate2D(37.776880, -122.418485), "i", "sub2", "id2"));
            pins.Add(new BasicMapAnnotation(new CLLocationCoordinate2D(37.786775, -122.417390), "j", "sub3", "id3"));
            pins.Add(new BasicMapAnnotation(new CLLocationCoordinate2D(37.796685, -122.416283), "k", "sub4", "id4"));

            var currentLocation = new LocationService().GetCurrentLocation();
            var visibleRegion = BuildVisibleRegion(currentLocation);

            mapView = BuildMapView(true);
            mapView.SetRegion(visibleRegion, true);

            this.View.AddSubview(mapView);

            // i have a vague idea that this delegate helps to redraw pins as user moves around screen
            mapView.Delegate = new MapViewDelegate();

            // this pin sometimes has a working callout that activates an alert and sometimes doesnt
            var testAnnotationX = new BasicMapAnnotation (new CLLocationCoordinate2D(37.786999,-122.500222), 
                                                     "made in viewdidload", "outside", "id5");
            mapView.AddAnnotation(testAnnotationX);

            // this pin collection also sometimes works but most often not
            mapView.AddAnnotations(pins.ToArray());
        }

        private MKMapView BuildMapView(bool showUserLocation)
        {
            var view = new MKMapView()
            {
                ShowsUserLocation = showUserLocation, 
            };

            view.Delegate = new MapViewDelegate();

            var testAnnotationY = new BasicMapAnnotation (new CLLocationCoordinate2D(37.800000, -122.450777), 
                                                    "made in buildmapview", "inside", "id6");

            view.AddAnnotation(testAnnotationY);

            view.SizeToFit();
            view.Frame = new RectangleF(0, 0, this.View.Frame.Width, this.View.Frame.Height);
            return view;
        }


        protected class MapViewDelegate : MKMapViewDelegate {
            protected string annotationIdentifier = "BasicAnnotation";
            UIButton detailButton; // avoid GC


            public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)
            {
                if (annotation is MKUserLocation) return null;  //ignore user marker

                annotationIdentifier = (annotation as BasicMapAnnotation).Id;

                // try and dequeue the annotation view
                MKAnnotationView annotationView = mapView.DequeueReusableAnnotation(annotationIdentifier);   
                // if we couldn't dequeue one, create a new one
                if (annotationView == null)
                {
                    annotationView = new MKPinAnnotationView(annotation, annotationIdentifier);
                    //annotationView.RightCalloutAccessoryView = new UIButton(UIButtonType.DetailDisclosure); //- not required as its at bottom??

                    // configure our annotation view properties 
                    annotationView.CanShowCallout = true;
                    (annotationView as MKPinAnnotationView).AnimatesDrop = true;
                    (annotationView as MKPinAnnotationView).PinColor = MKPinAnnotationColor.Green;
                    annotationView.Selected = true;


                    // you can add an accessory view; in this case, a button on the right and an image on the left
                    detailButton = UIButton.FromType(UIButtonType.DetailDisclosure);
                    detailButton.TouchUpInside += (s, e) => {
                        Console.WriteLine ("Clicked");
                        new UIAlertView("Annotation Clicked", "You clicked on " +
                                        (annotation as MKAnnotation).Coordinate.Latitude.ToString() + ", " +
                                        (annotation as MKAnnotation).Coordinate.Longitude.ToString() , null, "OK", null).Show();
                    };

                    annotationView.RightCalloutAccessoryView = detailButton;
                }
                else // if we did dequeue one for reuse, assign the annotation to it
                    annotationView.Annotation = annotation;
                /*
                // configure our annotation view properties
                annotationView.CanShowCallout = true;
                (annotationView as MKPinAnnotationView).AnimatesDrop = true;
                (annotationView as MKPinAnnotationView).PinColor = MKPinAnnotationColor.Green;
                annotationView.Selected = true;
                */



                // fix and uncomment
                //annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromBundle("29_icon.png"));
                return annotationView;
            }     

            // as an optimization, you should override this method to add or remove annotations as the
            // map zooms in or out.
            public override void RegionChanged (MKMapView mapView, bool animated) {}
        }


        private MKCoordinateRegion BuildVisibleRegion(CLLocationCoordinate2D currentLocation)
        {
            var span = new MKCoordinateSpan(0.2,0.2);
            var region = new MKCoordinateRegion(currentLocation,span);

            return region;
        }



        public override void DidReceiveMemoryWarning ()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();

            // Release any cached data, images, etc that aren't in use.
        }


        public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
        {
            // Return true for supported orientations
            return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
        }
    }

    public class BasicMapAnnotation : MKAnnotation{
        public override CLLocationCoordinate2D Coordinate {get;set;}
        string title, subtitle;
        public override string Title { get{ return title; }}
        public override string Subtitle { get{ return subtitle; }}

        public string Id {get ;set;}

        public BasicMapAnnotation (CLLocationCoordinate2D coordinate, string title, string subtitle, string id) {
            this.Coordinate = coordinate;
            this.title = title;
            this.subtitle = subtitle;
            this.Id = id;
        }
    }


    public class LocationService
    {
        private CLLocationManager locationManager;

        public LocationService()
        {
            locationManager = new CLLocationManager();
        }

        public CLLocationCoordinate2D GetCurrentLocation()
        {
            //dirty for now just to get some info.
            locationManager.StartUpdatingLocation();
            while(locationManager.Location == null);
            locationManager.StopUpdatingLocation();

            //return new CLLocationCoordinate2D ( 37.786995, -122.419280);
            return locationManager.Location.Coordinate;
        }
    }
}

错误:

堆栈跟踪:

at(wrapper managed-to-native)MonoTouch.UIKit.UIApplication.UIApplicationMain(int,string [],intptr,intptr)   在/Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38中的MonoTouch.UIKit.UIApplication.Main(string [],string,string)[0x0004c]   at singleview.Application.Main(string [])[0x00000] in ... / singleview / Main.cs:17   at(wrapper runtime-invoke).runtime_invoke_void_object(object,intptr,intptr,intptr)

原生堆栈跟踪:

0   singleview                          0x00091eac mono_handle_native_sigsegv + 284
1   singleview                          0x00005788 mono_sigsegv_signal_handler + 248
2   libsystem_c.dylib                   0x938658cb _sigtramp + 43
3   ???                                 0xffffffff 0x0 + 4294967295
4   UIKit                               0x0274f258 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
5   UIKit                               0x02810021 -[UIControl sendAction:to:forEvent:] + 66
6   UIKit                               0x0281057f -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 578
7   UIKit                               0x0280f6e8 -[UIControl touchesEnded:withEvent:] + 546
8   UIKit                               0x0277ecef -[UIWindow _sendTouchesForEvent:] + 846
9   UIKit                               0x0277ef02 -[UIWindow sendEvent:] + 273
10  UIKit                               0x0275cd4a -[UIApplication sendEvent:] + 436
11  UIKit                               0x0274e698 _UIApplicationHandleEvent + 9874
12  GraphicsServices                    0x04d40df9 _PurpleEventCallback + 339
13  GraphicsServices                    0x04d40ad0 PurpleEventCallback + 46
14  CoreFoundation                      0x012bfbf5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
15  CoreFoundation                      0x012bf962 __CFRunLoopDoSource1 + 146
16  CoreFoundation                      0x012f0bb6 __CFRunLoopRun + 2118
17  CoreFoundation                      0x012eff44 CFRunLoopRunSpecific + 276
18  CoreFoundation                      0x012efe1b CFRunLoopRunInMode + 123
19  GraphicsServices                    0x04d3f7e3 GSEventRunModal + 88
20  GraphicsServices                    0x04d3f668 GSEventRun + 104
21  UIKit                               0x0274bffc UIApplicationMain + 1211
22  ???                                 0x0f4d71ad 0x0 + 256733613
23  ???                                 0x0f4d4e40 0x0 + 256724544
24  ???                                 0x0f4d4a48 0x0 + 256723528
25  ???                                 0x0f4d4b9e 0x0 + 256723870
26  singleview                          0x00009b52 mono_jit_runtime_invoke + 722
27  singleview                          0x0016d02e mono_runtime_invoke + 126
28  singleview                          0x00171224 mono_runtime_exec_main + 420
29  singleview                          0x00176615 mono_runtime_run_main + 725
30  singleview                          0x000671e5 mono_jit_exec + 149
31  singleview                          0x00204fd4 main + 1988
32  singleview                          0x00002b75 start + 53

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
 a fatal error in the mono runtime or one of the native libraries 
 used by your application.
=================================================================

2 个答案:

答案 0 :(得分:0)

看起来好老的GC错误。

看看Monotouch-Samples应用程序正是这个类和行:

https://github.com/xamarin/monotouch-samples/blob/master/MapCallouts/MainViewController.cs#L108

您需要将所有Pinview存储在某个Collection中,因此垃圾收集不会尝试收集它们。

答案 1 :(得分:0)

'var testAnnotationX'怎么样?您可能还需要移动它。