2

我只有在 MonoTouch 5.4 中才有这个问题。DrawMapRect 是多线程的,但我这里需要使用 RectForMapRect。我可以在没有 InvokeOnMainThread 的情况下做到这一点吗?

错误:

MonoTouch.UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread.
  at MonoTouch.UIKit.UIApplication.EnsureUIThread () [0x00019] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:49
  at MonoTouch.MapKit.MKOverlayView.RectForMapRect (MKMapRect mapRect) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/MapKit/MKOverlayView.g.cs:146
  at MapTest.MyMKOverlayView.DrawMapRect (MKMapRect mapRect, Single zoomScale, MonoTouch.CoreGraphics.CGContext context) [0x00009] in /Users/kirill/Desktop/MapTest/MapTest/MapTestViewController.cs:38

源代码在这里:

using System;
using System.Drawing;

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.MapKit;

namespace MapTest
{
    public class MyMKMapView : MKMapView
    {
        public MyMKMapView(RectangleF frame) : base(frame)
        {
            GetViewForOverlay = GetViewForOverlayImp;
        }

        private MKOverlayView GetViewForOverlayImp(MKMapView mapView, NSObject overlay)
        {
            return new MyMKOverlayView();
        }

        public void AddNewOverlay()
        {
            AddOverlay(new MyMKOverlay());
        }
    }

    public class MyMKOverlayView : MKOverlayView
    {
        public MyMKOverlayView() : base()
        {

        }

        public override void DrawMapRect(MKMapRect mapRect, float zoomScale, MonoTouch.CoreGraphics.CGContext context)
        {
            base.DrawMapRect(mapRect, zoomScale, context);
            RectForMapRect(new MKMapRect());
        }
    }

    public class MyMKOverlay : MKOverlay
    {
        public override MKMapRect BoundingMapRect
        {
            get
            {
                return new MKMapRect(10 , 10 , 10 , 10);
            }
        }

        public MyMKOverlay() : base()
        {

        }
    }

    public partial class MapTestViewController : UIViewController
    {
        private MyMKMapView _map;

        public MapTestViewController() : base ("MapTestViewController", null)
        {
            _map = new MyMKMapView(View.Bounds);
            View.AddSubview(_map);
        }

        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 void ViewDidLoad()
        {
            base.ViewDidLoad();
            // Perform any additional setup after loading the view, typically from a nib.
        }

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

            // Clear any references to subviews of the main view in order to
            // allow the Garbage Collector to collect them sooner.
            //
            // e.g. myOutlet.Dispose (); myOutlet = null;

            ReleaseDesignerOutlets();
        }

        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            _map.AddNewOverlay();
        }

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

行错误RectForMapRect(new MKMapRect())

4

1 回答 1

2

此检查是 MonoTouch 5.4 的新功能。默认情况下,UI 线程检查仅在DEBUG构建上启用。您可以在构建时手动:

  • --disable-thread-check使用;禁用它(在 DEBUG 上)或者
  • --force-thread-check使用;启用它(在发布时)

您也可以在运行时使用CheckForIllegalCrossThreadCalls.

可能不需要检查 Apple 关于线程安全的文档不是很清楚(与 MSDN 不同)。如果您发现这种情况(或只是不确定),请填写错误报告

于 2012-09-10T12:11:52.017 回答