When the user switches to another program and then back again., the original program's view will be replaced by a new view from another program. So when the user switches back to the original program, would viewDidLoad be called the second time ?
Am asking this because if this is the case, then the initialization code placed inside viewDidLoad would be executed every time the user switches the screen back and forth. And this could result in reseting views and loosing unfinished works of the user ...
(Above is from the op)
In those cases there are two methods to be called:
reopening a backgrounded app (from task manager or from springboard again)
unlocking device which is locked when the app is active.
after phone calls
notification center dismissal
task manager dismissal (double tap home button & double tap again)
Don't 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 the controller's init method, like this:
The
initWithNibName:bundle:
method is called before the view is loaded from the nib, and is only called once in the lifespan of the view controller.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.If you do set stuff up in
viewDidLoad
(e.g. adding subviews programmatically) you should always unset them again inviewDidUnload
.Think of
viewDidLoad
andviewDidUnload
as being like the init/dealloc for the view property of the view controller. For stuff that relates to the views, create and release it in those methods. For stuff that relates to the controller itself, create and release it ininitWithNibName
anddealloc
.UPDATE: On iOS 6 and later,
viewDidUnload
is never called any more (unless the view is explicitly set to nil in the code), and soviewDidLoad
will typically only be called once in the life of a view controller. This makes the advice above less critical, but it's still best practice, and still necessary if you need to support iOS 5 and earlier.UPDATE 2: If you are loading your view controller from a Storyboard (which is now the recommended practice) instead of creating it programmatically then
initWithNibName:bundle:
will not be called. UseinitWithCoder:
orawakeFromNib
to initialize your controller instead.From the docs:
So, it is called whenever the view controller has its views loaded into memory. This could be the first time the view is loaded and never again, or every time the view is made visible if your view unloads constantly (
viewDidUnload
due to memory constraints, etc.)-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. A view controller won't unload its view just because the view is hidden, but it might do so if memory starts to run low.A view controller should know the state of its views and be able to set them up as necessary in its
-viewDidLoad
method. Views shouldn't be used to store state -- nothing should be irrevocably lost just because the view is unloaded.@Nick Lockwood provides excellent information, but there are a few more things to remember.
First,
initWithNibName:bundle:
is not called if the view controller is instantiated from a nib file or storyboard. In that case,initWithCoder:
andawakeFromNib
are called instead. This situation used to be somewhat uncommon on iOS, but with the addition of storyboards it is now much more common for view controllers to bypassinitWithNibName:bundle:
.I recommend putting non-UI initialization code in a separate method (I call mine
setup
) and call it from bothinitWithNibName:bundle:
andawakeFromNib
. But I only do this if it's important that that initialization only run once. Otherwise I put it inviewWillAppear:
to be as lazy-load as possible.Second, you should not do anything that references
self.view
ininit...
orawakeFromNib
. You should never referenceself.view
untilviewDidLoad
is called (otherwise you will force the nib file to be loaded sooner than it is needed). UI-related things should go inviewDidLoad
if they're related to setting up the views, orviewWillAppear:
if they're related to configuring the views (i.e. loading them with data).So the way I usually set these things up: