Bug 22490 - ViewDidLoad is being called before the constructor.
Summary: ViewDidLoad is being called before the constructor.
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 3.x
Hardware: PC Windows
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-08-28 20:54 UTC by djvoracious
Modified: 2014-09-08 09:41 UTC (History)
3 users (show)

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

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:
Status:
RESOLVED NOT_ON_ROADMAP

Description djvoracious 2014-08-28 20:54:19 UTC
It seems that when inheriting from the UITabBarController, the constructor in the UITabBarController class is calling ViewDidLoad within its constructor.

This makes having dependency injection impossible. The work around is currently using the ViewDidAppear instead.

    [Register("AppDelegate")]
    public class AppDelegate : UIApplicationDelegate
    {
        public UIViewController MainController { get; set; }

        public UIWindow Window { get; set; }

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            Window = new UIWindow(UIScreen.MainScreen.Bounds);

            MainController = new MyTabController("Some Value");

            Window.RootViewController = MainController;

            Window.MakeKeyAndVisible();

            return true;
        }

    }

    public class MyTabController : UITabBarController
    {
        private readonly string _value;

        public MyTabController(string value)
        {
            _value = value;
            Console.WriteLine("Constructor being called with value : {0}", value);
        }

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

            Console.WriteLine("ViewDidLoad being called with value : {0}", _value);
        }
    }
Comment 1 Parmendra Kumar 2014-08-29 09:12:16 UTC
I have checked this issue and able to reproduce this, To reproduce this issue I
have followed the sample code mentioned in bug description. And observed that ViewDidLoad is being called before the constructor.

Screencast:http://www.screencast.com/t/6m9zmRO1Z4c

Output Log:https://gist.github.com/Parmendrak/187fd9174bfbef8b2a44

Environment info:

Microsoft Visual Studio Professional 2013
Version 12.0.30723.00 Update 3
Microsoft .NET Framework
Version 4.5.51641

Xamarin   3.3.47.0 (0b2a123923812a88ed3091909478dbe9e0111f00)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android
Comment 2 djvoracious 2014-08-29 20:54:00 UTC
Great. For the time being, my work around seems to get me past. However, it isn't optimal, given the number of times that this screen in my application is called.

I like the ScreenCast technology
Comment 3 Rolf Bjarne Kvinge [MSFT] 2014-09-08 09:41:21 UTC
ViewDidLoad is called by iOS, there's nothing we can do about it.

Here's a stacktrace with the relevant native+managed frames:

    frame #6: 0x0d778584 testapp.AppDelegate/MyTabController:ViewDidLoad () + 0x7c (0xd778508 0xd778597) [0x7a964340 - MonoTouch]
    frame #7: 0x0ccdb8bd (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) + 0x13d (0xccdb780 0xccdb8e0) [0x7a964340 - MonoTouch]
    frame #8: 0x001a155f testapp`mono_jit_runtime_invoke(method=<unavailable>, obj=<unavailable>, params=<unavailable>, exc=<unavailable>) + 751 at mini.c:6738
    frame #9: 0x00235f2f testapp`mono_runtime_invoke(method=0x7a18efc4, obj=0x0cd16c18, params=<unavailable>, exc=<unavailable>) + 127 at object.c:2831
    frame #10: 0x000be9b4 testapp`native_to_managed_trampoline_1(self=0x7a9cd170, _cmd=0x01731589, managed_method_ptr=0x004018f0, r0=0x003111f0, r1=0x00311260) + 292 at registrar.m:29
    frame #11: 0x000c2a4a testapp`-[testapp_AppDelegate_MyTabController viewDidLoad](self=0x7a9cd170, _cmd=0x01731589) + 74 at registrar.m:939
    frame #12: 0x00fb0937 UIKit`-[UITabBarController initWithNibName:bundle:] + 221
    frame #13: 0x00f682d9 UIKit`-[UIViewController init] + 49
    frame #14: 0x0d7731ac (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:IntPtr_objc_msgSendSuper (intptr,intptr) + 0x74 (0xd773138 0xd773227) [0x7a964340 - MonoTouch]
    frame #15: 0x0d777d2c MonoTouch.UIKit.UITabBarController:.ctor () + 0x114 (0xd777c18 0xd777d5f) [0x7a964340 - MonoTouch]
    frame #16: 0x0d777b88 testapp.AppDelegate/MyTabController:.ctor (string) + 0x28 (0xd777b60 0xd777bfb) [0x7a964340 - MonoTouch]
    frame #17: 0x0d776320 testapp.AppDelegate:FinishedLaunching (MonoTouch.UIKit.UIApplication,MonoTouch.Foundation.NSDictionary) + 0x110 (0xd776210 0xd7763c3) [0x7a964340 - MonoTouch]