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?
-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.
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.
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.
I just finished doing some research on this topic so I thought I'd share a few of the things I learned.
There's nothing wrong with using awakeFromNib
with views for the iPhone. See this Apple Dev document.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With