Bug 15811 - Setter for [Weak]Delegate in MKMapView inheritor doesn't seem to be working.
Summary: Setter for [Weak]Delegate in MKMapView inheritor doesn't seem to be working.
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 7.0.2.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2013-10-30 07:31 UTC by folex
Modified: 2013-10-30 10:08 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Screenshot of debugger Watch. (93.62 KB, image/png)
2013-10-30 07:31 UTC, folex

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description folex 2013-10-30 07:31:03 UTC
Created attachment 5272 [details]
Screenshot of debugger Watch.

My class UserAroundMap inherits from MKMapView.
UserAroundMapDelegate inherits from MKMapViewDelegate.

When I do

    var del = new UserAroundMapDelegate(GetViewForAnnotationInternal);
    WeakDelegate = del; //Or "Delegate = del;"

Delegate property getter returns instance of UserAroundMapDelegate at first, but then it becomes an instance of "MonoTouch.MapKit.MKMapView+_MKMapViewDelegate", thus lacking all of the methods of my delegate. E.g. this code:

    var newAnn = new UserAnnotation(info);

    OSTools.InvokeInBackground(() => {
        InvokeOnMainThread(() => {
            newAnn.Coordinate = Region.Center;
            var annotView = GetViewForAnnotation(this, newAnn); //GetViewForAnnotation is null
            var convertedAnnotation = annotView as UserAnnotationView;

throws NullReferenceException.

For me it seems like selector "setDelegate:" that sent to MKMapView doesn't work as it should.

I've attached screenshot of debugger Watch.

=== Xamarin Studio ===

Version 4.0.13 (build 38)
	Mono 3.2.3 ((no/8d3b4b7)
	GTK+ 2.24.20 theme: Raleigh
	GTK# (
	Package version: 302030000

=== Apple Developer Tools ===

Xcode 5.0.1 (3335.23)
Build 5A2053

=== Xamarin.iOS ===

Version: (Business Edition)
Hash: 57edee2
Build date: 2013-04-10 18:05:51-0400

=== Build Information ===

Release ID: 400130038
Git revision: 07afec667f7be5d0ee511eb7115bbac6377fbae8
Build date: 2013-09-24 08:53:29+0000
Xamarin addins: 61140345a5b109633a94409edcbc7a4c19a425c6
Comment 1 Sebastien Pouliot 2013-10-30 07:49:47 UTC
> but then it becomes an instance of
> "MonoTouch.MapKit.MKMapView+_MKMapViewDelegate"

That happens when you use events. Short story you cannot mix events and *Delegate types - because the former use the later (there's no .NET-like events in ObjC). Long story in [1].

If you're not using C# events then please attach a test case and we'll look into it.

[1] http://spouliot.wordpress.com/2012/03/26/events-vs-objective-c-delegates/
Comment 2 folex 2013-10-30 09:11:55 UTC
Thanks for quick response.

Does MKMapView contains builtin events besides

* GetViewForAnnotation
* GetViewForOverlay
* OverlayRenderer


Cause I don't use any of them. I was, but after your advice, I've commented it out and nothing changed.
I can't create test project right now, I have no time. I will, but not right now.

Can I find code that overrides my delegate in Assembly Browser, so I could get better understanding of what happens under the hood, and possibly shoot this bug by myself?
Comment 3 folex 2013-10-30 09:14:42 UTC
I also don't use anything from 
// Events

Comment 4 folex 2013-10-30 09:25:34 UTC
Look at that:

		private MKMapView._MKMapViewDelegate EnsureMKMapViewDelegate ()
			NSObject nSObject = this.WeakDelegate;
			if (nSObject == null || !(nSObject is MKMapView._MKMapViewDelegate))
				nSObject = new MKMapView._MKMapViewDelegate ();
				this.WeakDelegate = nSObject;
			return (MKMapView._MKMapViewDelegate)nSObject;

As far as I understand it says that if WeakDelegate not your helper-delegate (_MKMapViewDelegate), let's override it with an instance of _MKMapViewDelegate!

That's not correct behaviour.
Comment 5 folex 2013-10-30 09:52:02 UTC
It's really sucks that I can't edit or remove my comments.

Anyway, I was wrong and EnsureMKMapViewDelegate is OK, I just thought it was used somewhere not in events. Sorry for that. 

But problem still persists.
Comment 6 Sebastien Pouliot 2013-10-30 09:59:56 UTC
> If you're not using C# events then please attach a test case and we'll look
> into it.
Comment 7 folex 2013-10-30 10:04:43 UTC
> I can't create test project right now, I have no time. I will, but not right now.

Anyway, I found the problem and solved it.

1. Call EnsureMKMapViewDelegate in Watch was bad idea.
2. I confused GetViewForAnnotation and ViewForAnnotation. And every time I called GetViewForAnnotation, I got NullReferenceException cause EnsureMKMapViewDelegate was called and my delegate was overriden.

Sorry for bothering. 

Mark it as INVALID please.
Comment 8 Sebastien Pouliot 2013-10-30 10:08:18 UTC
Yes. Using the Watch (or the Immediate) pad can have side effects.

Glad you solved it!