Thomas Bandt

Über mich | Kontakt | Archiv

Monotouch: ViewDidLoad gets called before constructor

Note to myself: Never ever call any member of a base class like "View" or "TableView" within your controllers constructor, if you depend on fields in your ViewDidLoad() method set later there.

Bad example:

public class MyController : UITableViewController
{
	private string _title;

	public MyController(string title)
	{
		View.BackgroundColor = UIColor.White;

		_title = title;
	}

	public override void ViewDidLoad()
	{
		Console.WriteLine(_title); // IS NULL!
	}
}

I was hunting that ghost for half an hour and remembered that I did run into that phenomenon a year or so ago. After some search I found the answer of Rolf Bjarne Kvinge he gave me in those days, too:

"This usually happens when in a base class you call a virtual property, which ends up calling a virtual member on the derived class.

This is easy to see if you get a stack trace in the virtual method (such as ViewDidLoad) in the derived class, in which case you'll easily see what's happening."

Or in other words: If you do what I did in my example, ViewDidLoad() will always be called before _title is set - from within your constructor, what looks like the constructor is called afterwards.

What a waste of time ;-).

Kommentare

  1. Alex schrieb am Donnerstag, 8. Mai 2014 15:37:00 Uhr:

    _title = title;
    View.BackgroundColor = UIColor.Gray;

    works BTW.
  2. Thomas schrieb am Donnerstag, 8. Mai 2014 15:57:00 Uhr:

    Sure, as ViewDidLoad() is called at the moment you access the member. But I wouldn't recommend to keep doing so, as it's a bit error-prone.
  3. Alex schrieb am Donnerstag, 8. Mai 2014 15:57:00 Uhr:

    On the other hand, inside ViewDidLoad(), something like
    View.BackgroundColor = UIColor.Red;

    doesn't update the View.BackgroundColor when already set inside the constructor.
  4. Alex schrieb am Donnerstag, 8. Mai 2014 16:00:00 Uhr:

    We should rely on ReSharper here: "Virtual member call in constructor" ;-)
  5. Thomas schrieb am Donnerstag, 8. Mai 2014 16:22:00 Uhr:

    No ReSharper available - Xamarin.Studio on Mac ;-(

    I think at the moment, where you're accessing View.BackgroundColor from your constructor, ViewDidLoad() gets called, so whatever you set there gets overwritten afterwards with the value from inside the constructor.
  6. Alex schrieb am Donnerstag, 8. Mai 2014 16:32:00 Uhr:

    Makes sense.


« Zurück  |  Weiter »