Bug 1449 - Outlet property cannot be set from xib that uses subclass
Summary: Outlet property cannot be set from xib that uses subclass
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 5.0
Hardware: Macintosh Mac OS
: Normal major
Target Milestone: Untriaged
Assignee: Bugzilla
: 11455 ()
Depends on:
Reported: 2011-10-12 09:24 UTC by Marco
Modified: 2013-07-22 13:24 UTC (History)
9 users (show)

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

Example project (1.31 MB, application/zip)
2011-10-12 09:24 UTC, Marco
Exmple project ver 2 (1.31 MB, application/zip)
2011-10-12 10:24 UTC, Marco

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 Marco 2011-10-12 09:24:14 UTC
Created attachment 680 [details]
Example project

I migrated my application from monodevelop 2.6 to 2.8 and from XCode 3 to XCode 4.
If I override a UIViewController the method ViewdidLoad doesn't raised more from both the base view than from overrided view.
In the attached example: I created the BaseView; ProView is inherited from the base view. 
The main class raised the "Object reference not set to an instance of an object" exception when try to set the button's title on the baseView, but the button exists.
Comment 1 Mikayla Hutchinson [MSFT] 2011-10-12 09:40:29 UTC
Did you intend for the ProView claa to load BaseView.xib? That's what your code is doing. ProView.xib isn't used at all.
Comment 2 Marco 2011-10-12 09:48:02 UTC
Sorry, I missed to add to the sample the LoadNib command

this is the ProView Class corrected

namespace OverrideProject
	public partial class ProView : BaseView
		//loads the ProView.xib file and connects it to this object
		public ProView () : base ()
		public override void ViewDidLoad ()
			MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("ProView", this, null);
			base.ViewDidLoad ();
			BtnSlave2.SetTitle ("Button 2 - From Pro View", UIControlState.Normal);
Comment 3 Mikayla Hutchinson [MSFT] 2011-10-12 09:53:59 UTC
The base BaseView ctor is still passing the "BaseView" nib name to the UIViewController ctor, so ProView is still loading two nibs. I don't know exactly what sequence they're loaded, but it's possible you may not end up with the one you expect.

I would suggest adding another ctor to BaseView:
protected BaseView (string nibName) : base (nibname, null)

Then ProView can load the correct nib from its ctor:
public ProView () : base ("ProView")
Comment 4 Marco 2011-10-12 10:23:32 UTC
I tried with your suggestion but I still have the same problem.

Attached the Example project updated.
Comment 5 Marco 2011-10-12 10:24:27 UTC
Created attachment 681 [details]
Exmple project ver 2
Comment 6 Marco 2011-10-13 08:14:06 UTC
Hi, any news about this issue?

Comment 7 Mikayla Hutchinson [MSFT] 2011-10-18 06:21:56 UTC
The problem is that ProView and BaseView both define an outlet called BtnMain1. When the xib is instantiated, the button is connected to the most derived one, i.e. the one on ProView, so the one on BaseView is null.

However, even after solving this problem by removing the BtnMain1 from ProView, I get the following error when loading the xib:

Unhandled Exception: System.Exception: Failed to find selector setBtnMain1: on ProView
  at MonoTouch.ObjCRuntime.Runtime.GetMethod (IntPtr klass, IntPtr selptr) [0x00022] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:141 
  at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetMethod (intptr,intptr)
  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)

This looks to me like a problem with the MT obj-c bridge, so I'm reassigning.
Comment 8 Mikayla Hutchinson [MSFT] 2011-10-18 06:36:15 UTC
I tested a xib that does this, i.e. connects to outlets on the controller class and controller's superclass, and it works in obj-c.
Comment 9 Marco 2011-10-18 06:55:18 UTC
Then, Can you confirm that it's a problem with MT?
Do you know if this issue will be solved in the next released? 
Now we have some solutions with this logic, and this problem is a blocker...

Comment 10 Mikayla Hutchinson [MSFT] 2011-10-19 04:28:42 UTC
You might be able to work around it by making the base definition virtual, then trivially overriding it in the subclass, e.g. in the base class do:

protected virtual MonoTouch.UIKit.UIButton BtnMain1 { get; set; }

and in the subclass, do:

protected override MonoTouch.UIKit.UIButton BtnMain1 {
    get { return base.BtnMain1; }
    set { base.BtnMain1 = value; }

You should move these to the non-designer class parts to prevent the designer from altering them.
Comment 11 Marco 2011-11-02 12:51:29 UTC
sorry for delay. I tried your workaround but in the "designer.cs" is not possibile to use object (in the subclass) from the base class because the objects are declared private. 
Moreover this workaround it's unusable because every time I change the xib from IB the designer file is regenerated automatically.
Comment 12 Mikayla Hutchinson [MSFT] 2011-11-02 15:32:53 UTC
Please note my comment about moving the outlets to the non-designer class part so that the designer does not alter them.
Comment 13 Marco 2011-11-09 11:34:31 UTC
the suggested workaround, even if it could work, it's unusable.
For every "standard" view I have to manually move and  modify outlets definitions marking them as virtual in order to override them in the subclasses.
Moreover everytime I'll add a new control to the standard view (or remove an existing one) I'll have to manually update all subclasses.
This is not inheritance.
Any news about the task reassingning? Do you have an idea if this issue will be resolved and which release will include the fix?
Thanks in advance!
Comment 14 Daniel 2011-12-24 19:04:00 UTC
I've just tripped on the same issue. Any word on a resolution or a better workaround?
Comment 15 Andy 2012-01-04 11:45:25 UTC
Same here. The workaround 'works', but I suspect one could easily hit the problem multiple times at random.

My solution in these cases is becoming, even more now, to move all the design to code and ignore IB
Comment 16 Chris Hatton 2012-05-14 07:31:13 UTC
I would like to bump this issue.

This decision to make outlets private seriously cripples the usefulness of XIB integration - with use of ViewController base class becoming impossible. These outlets should be protected access in my opinion... 

Any word on whether these can be changed to protected, and if not, what is the reason? Thanks.
Comment 17 Mikayla Hutchinson [MSFT] 2012-05-14 10:47:27 UTC
MD importing outlets as private doesn't make anything impossible. Why do you say it does?
Comment 18 Miguel de Icaza [MSFT] 2013-02-11 22:14:12 UTC
Someone was asking today on the mailing lists whether we should flag outlets as "internal".

I do not have strong opinions on this, but I am adjusting the priorities.
Comment 19 Mikayla Hutchinson [MSFT] 2013-02-12 01:30:39 UTC
This bug is not about the accessibility of outlets, it's about a bug in MonoTouch's ObjC bridge.
Comment 20 Rolf Bjarne Kvinge [MSFT] 2013-03-14 19:46:09 UTC
The problem mentioned in comment 7 (Failed to find selector setBtnMain1: on ProView) has been fixed (with the new registrar).

The original problem still exists though (the most derived outlet is used always), but that doesn't look like a bug in MonoTouch (imho the generated code should not duplicate outlets in the first place, but I might be wrong about this).
Comment 21 Mikayla Hutchinson [MSFT] 2013-03-14 21:15:44 UTC
There is no "generated code" there is only "synced code". In the original code the user had created a duplicate output, probably to work around the real issue which I described in comment 7, so I think we can mark this as fixed.
Comment 22 Mikayla Hutchinson [MSFT] 2013-03-28 00:22:43 UTC
*** Bug 11455 has been marked as a duplicate of this bug. ***
Comment 23 Rolf Bjarne Kvinge [MSFT] 2013-07-15 18:57:43 UTC
The fix mentioned in comment #20 (the new registrar) is not enabled by default (because in some cases the new registrar will error out on invalid code we previously allowed, effectively breaking existing code).

To enable this fix add this to the additional mtouch arguments in the project's iOS Build options:

--registrar:dynamic (for simulator builds)
--registrar:static (for device builds)
Comment 24 Rolf Bjarne Kvinge [MSFT] 2013-07-22 13:24:05 UTC
Note that the latest beta (6.3.8) is broken wrt comment 23, but it's be fixed for the final 6.4 release.