Camputer
Camputer

Reputation: 387

MonoTouch custom UIButton crashes on load: Selector invoked from objective-c on a managed object that has been GC'd

I am using MonoTouch and have created a class MyButton that extends UIButton. This is actually a simplified example of the same problem I was having with a custom UIScrollView. MyButton extends UIButton and adds some methods to do something simple like increment and decrement a counter (this is just a test case). I also include '[Register("MyButton")]' before my class definition so that it registers with Interface Builder (IB) so that I can add a UIButton and specify its class as MyButton.

What works: I can add an instance of MyButton programmatically to my main view and it displays properly and functions as expected.

What doesn't work: If I try to add a UIButton from IB and specify its class as MyButton, then add an outlet and also specify it is a MyButton type then my app crashes while trying to load the main view with the exception: Unhandled managed exception: Selector invoked from objective-c on a managed object of type iOSCustomUIView.MyButton (0xC2F40D0) that has been GC'ed (System.Exception).

I have found similar questions that have this problem but with view controllers, not views. So I understand that the error is similar, but in the case of a view controller references are lost when pushing new controllers onto the stack, etc. In my case, I don't know why my object has been GC'd before anything has loaded.

I have tried creating additional private member variables to reference my MyButton outlet (btnIncrement), but this did not help. I set breakpoints and the crash occurs when trying to instantiate a new instance of my view controller: (from AppDelegate.cs)

    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        window = new UIWindow (UIScreen.MainScreen.Bounds);

        viewController = new iOSCustomUIViewViewController ();
        window.RootViewController = viewController;
        window.MakeKeyAndVisible ();

        return true;
    }

Is there anything I am missing in order to define a custom UIButton class and use it in IB? Is this a bug in MonoTouch?

Upvotes: 2

Views: 214

Answers (1)

Camputer
Camputer

Reputation: 387

I got a great response from adamkemp on the Xamarin forum. The solution is that I need to write a constructor that accepts an IntPtr p argument since that is the constructor called when view objects are created from xib files. In my case, I simply define the following constructor:

public MyButton(IntPtr p) : base(p)
{
    // Do initialization stuff here
}

Since I did not have this constructor defined, my object was likely never created. The log message saying that my object has been GC'd was a little misleading in this case. Now, my app views all load successfully.

Upvotes: 2

Related Questions