Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Description of initWithNibName, awakeFromNib and viewDidLoad?

Is there a good overview of initWithNibName, awakeFromNib, and viewDidLoad that lays out the best way to use each of these and describes exactly what each does? I find these very confusing. In the template that's generated with a View Controller, the comment about initWithNibName says:

The designated initializer. Override to perform setup that is required before the view is loaded.

Except that this method never seems to be called (I'm using IB to set up the View Controller). So should I use awakeFromNib or viewDidLoad to initialize instead?

like image 607
Elisabeth Avatar asked Aug 06 '09 16:08

Elisabeth


People also ask

How many times does viewDidLoad get called?

-viewDidLoad will be called once whenever the view controller needs to load its view hierarchy. Obviously, that'll happen the first time that the controller accesses its view. If the view controller later unloads its view, then -viewDidLoad will be called again the next time the view is loaded.

Which method is called after viewDidLoad?

However, technically viewDidLoad will be called first. Show activity on this post. Yes, it is called before. ViewDidAppear - it is called when the view is visible to the user, here is the place to start an animation or something like that.


2 Answers

If you're creating your views in IB, then you should use viewDidLoad. That will be called every time the view is initialized to be put up. You use initWithNibName: when you're creating your view in code. You shouldn't use awakeFromNib with views for the iPhone.

The reason that initWithNibName is not seeming to be called is that interface builder actually creates a real instance of your view controller and then serializes that view. So, when you create the view controller in IB (add it to your project, basically), IB calls initWithNibName, but unless you have overridden the default encodeWithCoder:, any transient variables that you've set up there will be gone when the view is loaded from the nib (deserialized). This is generally okay since you usually want to set up your view with information specific to your applications current, running context rather than pre-determined initializers.

Even if you are programmatically creating views and view controllers, however, you can still put all the initialization in viewDidLoad. This is often better because if your view ends up getting cached (unloaded) and then brought back onto the screen, viewDidLoad can be called again while your initializer wouldn't necessarily be. For example, you create a view programmatically and push it onto a navigation controller's stack—later the view has been covered up and a memory warning is issued so the nav controller "unloads" your view but doesn't release the object—when the view comes back (other views get popped off), the nav controller will call viewDidLoad again so you can re-initialize, but initWithNib will not be called again. Note that this is a rare case and most people's applications will die horribly for other reasons at this point anyway, however.

like image 39
Jason Coco Avatar answered Oct 11 '22 14:10

Jason Coco


I just finished doing some research on this topic so I thought I'd share a few of the things I learned.

  1. There's nothing wrong with using awakeFromNib with views for the iPhone. See this Apple Dev document.

  2. initWithCoder is not a good place to do initialization when the view is loaded from a NIB file because other items in the same NIB file may or may not have been initialized at that point. So an outlet might still be nil, for example. All items in the same NIB file are guaranteed to be initialized properly when awakeFromNib is called.

  3. viewDidLoad is a good place to do setup work in the viewController.

So why would one want to use awakeFromNib in the view? One reason I can think of is if you have stuff you want to do after the view has been initialized and hooked up to the other objects in the NIB file, but you want to encapsulate it in the view only. This reduces linkage with the view controller.

like image 175
justme Avatar answered Oct 11 '22 12:10

justme