viewDidLoad of my RootViewController gets called by application:didFinishLaunchingWithOptions: and applicationDidBecomeActive: - ios

I am using a Storyboard with a UINavigationController that is set as "is initial View Controller". It's attached RootViewControllers. viewDidLoad method gets called after application:didFinishLaunchingWithOptions: and applicationDidBecomeActive:.
Why does that happen?

Because the view is loaded before your application becomes active. Active is defined as the point at which your application begins responding to events, and you need a view for this.

If you want to know why viewDidLoad method gets called after those methed I suggest you to read the app-launch-sequence-ios. It's the normal bootstrap execeution in every iOS application.
When you istantiate a controller with an associated view, the view for that controller takes some time to load in memory. viewDidLoad is not called immediately but only when the view has been loaded completely. Here you are sure that outlet for that view are linked correctly.
Hope it helps.

Related

Does viewDidload method call again on going back to a screen in navigation controller?

I am using navigation controller. I have pushed two viewcontroller to navigation stack. When I am coming back to viewcontroller1 from viewcontroller2 using back button of navigation bar then viewdidload method of viewcontroller1 is called again.But as much as I know viewdidload is called only once at loading time. So why is this happening? Please tell me.
Thanks!!
-(void)viewDidLoad called only when view controller is loaded
but if you want to call any method then you can write code in
-(void)viewWillAppear
this method called every time when your view is appear.
About viewDidLoad
viewDidLoad: is called every time your view controller's view is loaded, not just the first time. The controller's view can be loaded and unloaded multiple times during the lifespan of the controller and viewDidLoad will be called every time. It may be unloaded whenever it's not on screen, usually if memory is low.
Best practices
Remember not to do view controller initialisation in viewDidLoad. This is a common mistake. For stuff that should only happen once when the view controller is loaded, do it in one of the controller's init methods.
If you're popping/dismissing back to it, viewDidLoad is not generally called, but viewDidAppear will.
The exception to this is in iOS versions prior to 6.0, if you received a memory warning, your view could be unloaded, and it will be reloaded when you pop back.
As you are pushing the viewcontrollers, AFAIK they create a new instance of the view controller they are presenting. When you get back to viewController1 it's viewDidLoad will not be called but the viewController2 viewDidLoad will be called every time you move from viewController1 to viewController2. When you perform pop from viewController2 it is deallocated there itself

viewController's viewdidload called before appDelegate's method

I want to initialize some code before my viewDidLoad called , but it always go to viewDidLoad first and then it comes to the method applicationDidFinishLaunching.
I am unable to understand what is going on?
That is because AppDelegate instantiates its window and main view controller automatically before applicationDidFinishLaunching. You should uncheck for "Is Initial View Controller" in your storyboard and manually create window and its root view controller in applicationDidFinishLaunching.
The documentation for application:didFinishLaunchingWithOptions:
You should use this method to initialize your application and prepare
it for running. It is called after your application has been launched
and its main nib file has been loaded. At the time this method is
called, your application is in the inactive state. At some point after
this method returns, a subsequent delegate method is called to move
your application to the active (foreground) state or the background
state.
So the view is lazily loaded for view controllers once the the view property or method is called. When this happens viewDidLoad is called so if your window rootViewController property is set to your root ViewController in the nib then this is expected behavior.

About viewController's "viewDidLoad" and "viewWillAppear" methods

I've got a question regarding the two mentioned methods, since in my tests I don´t make clear the order they are called. I thought that, firstly, viewDidLoad is called when the viewController is loaded for first time (as the name indicates), and inmediately after the init method. Then, I thought that once viewDidLoad returns, viewWillAppear is called. If you display another viewController, and then you return to this one, then it should be already loaded and only viewWillAppear will be called.
However, while developing I make the impression that there is no order when calling viewDidLoad and viewWillAppear... I couldn´t find a clear description of this lifecycle in Apple's documentation, how does this actually work?
Thanks!
I would like to add to Caleb's answer: Don't confuse the view controller and the view! The name viewDidLoad clearly indicates that the method is invoked after the view has been loaded. It is the view controller that does the loading.
Some pointers regarding the lifecycle of views and the order in which messages are sent:
Not an official Apple document, but I find this diagram really useful because it includes pretty much all of UIViewController's lifecycle overrides.
In the section Resource Management in View Controllers from Apple's "View Controller Programming Guide" there is a flowchart that depicts how views are initially loaded. It explains loadView and viewDidLoad, also in conjunction with storyboards.
The section Responding to Display-Related Notifications from Apple's "View Controller Programming Guide" explains how to respond to views appearing and disappearing (viewWillAppear: et al)
If you are planning on implementing a container view controller: The UIViewController class reference has a good overview of how messages need to be sent by your subclass.
I'm stopping here. You can find more stuff yourself by googling for "uiviewcontroller life cycle".
-viewDidLoad is called when the controller loads its view, which is not necessarily right after initialization. View controllers don't load their views until they need them, either to display or for any other reason.
-viewWillAppear is called just before the view is displayed. This will be after -viewDidLoad, but you don't know exactly how long after. -viewWillAppear is called every time the view is displayed; -viewDidLoad will only be called a second time if the view is unloaded at some point (such as didReceiveMemoryWarning). These days that's unusual, but it can happen.
Or if the viewController is set to nil, which can usually happen if a view controller is kicked off the navigation stack, and therefore next time it is brought to the navigation stack it needs to call -viewDidLoad again.
I thought that, firstly, viewDidLoad is called when the viewController
is loaded for first time (as the name indicates), and inmediately after the init method
No. The name indicates that the controller's view has been loaded (not the controller itself). Actually the docs state that this method will get called after the view hierarchy has been loaded into memory (either via loadView or through a nib for example).
Then, I thought that once viewDidLoad returns, viewWillAppear is
called
Again, no. loadView (and as a consequence viewDidLoad) method will get called the first time that view property is to be accessed and is nil (which is the case when you're initializing a controller). Think of this simple scenario:
MyViewController *vc = [[MyViewController alloc] init];
UIView *view = vc.view; // <= loadView & viewDidLoad will fire but it certainly didn't appear...
However, while developing I make the impression that there is no order
when calling viewDidLoad and viewWillAppear...
Well there is an order. We know for sure that viewWillAppear will always be called after viewDidLoad (if both of them are to be called of course).
As you said, ViewDidLoad is only calling once after loading the view. So we can initialize the instances in the viewDidLoad. It is mainly meant for the initialization.
viewWillAppear will invoke whenever we reach to this view. So if there is any changes in UI, we can done it in viewWillAppear.
I ran a trace on when all these calls are made: http://thecodist.com/article/ios_arc_storyboards_and_uiviewcontroller_trace

Why popping to root view controller results in calling viewDidLoad sometimes?

I have a navigation based application and in the child view I have a button, tapping on which results in calling the popToRootViewController method.
-(IBAction)popToRootViewController
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
This should result in calling the viewWillAppear method of the rootViewController and it is happening in most of the cases. However, occasionally viewDidLoad of rootViewController is called. I am not able to find the reason behind it. Does any one has any idea why viewDidLoad is called sometimes?
On iOS 5 and Earlier, the System May Unload Views When Memory Is Low:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
viewDidLoad is called once when view controller's view is loaded first time.
viewWillAppear will be called after viewDidLoad method when view controller's view is loaded first time.
Now when ever u push or pop controller in navigationController, the visible controller's viewWillApper method will be called surely.
viewDidLoad, as the name implies, is called just after a view controller has loaded its view. If a view controller is no longer the frontmost controller, it may release its view to save memory (and it used to call viewWillUnload and viewDidUnload which are now deprecated in iOS 6). If this happens, when it comes to front again (or whenever something calls thecontroller.view), it will recreate the view (if is not Nib-based, it will call loadView), and then call viewDidLoad.

ViewController won't update after load

I got two viewControllers using a navigation bar. The first viewController displays some data I change on the second viewController.
So if I load the second viewController, a back button appears in the NavBar and I can change my values (and they are stored, I used the debugger). My problem is, after hitting the backButton to come to my firstView Controller, it does not call it's viewDidLoad method. It's clear, that there are no updated values at all, when this function is not called.
At the first start, the viewDidLoad method is called and does what I want it to do. After going back and forth between the viewControllers the method is not called again.
Any solutions?
Thanks!
EDIT:
SOLVED
I did not want to delete my question, maybe someone needs this too:
This method is called every time the view appears, it is probably not defined by default:
-(void)viewDidAppear:(BOOL)animated
{
NSLog(#"View appeared.");
}
But the update code (like [[self view] setNeedsDisplay];) in viewWillAppear.
To make it clear: viewDidLoad is called when your view is loaded. This happens at the first time the view is going to be displayed. When you then navigate to the next view the first view can (depending on your code) still be loaded. Therefore when you navigate back to that view viewDidLoad won't be called because the view is still there.
But every time the view is going to be shown (for example when you navigate back to this view) the method viewWillAppear and viewDidAppear will be called.
Hope that helps.
ViewDidLoad method will get called when there is view controller allocation-initialization happens. In the case of moving back in navigation controller, it is not creating any new view controllers, it is reusing previous references from navigation stack.
Hence viewDidLoad will not get called. As your view controller is already in memory stack. So it will just make the view to reappear on windows and it will call viewWillAppear respectively.

Resources