viewDidLoad vs init

UIKit Junior Swift 5.0+ iOS 17+ Reviewed By Alok Singh

Pick the fix

A custom init sets nameLabel.text = name, where nameLabel is an outlet. It crashes: unexpectedly found nil. Fix?

Options
Hint 1 of 1

When are outlets connected?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Store name in init and set the label in viewDidLoad

Correct. Outlets exist after the view loads.

Why not the others?
  • B Call loadViewIfNeeded() in init. It works, but loads the view early and defeats lazy loading.
  • C Make the outlet optional and use nameLabel?.text. It stops the crash but silently never sets the text.
  • D Move it to viewDidAppear. It works, but the empty label flashes before the text appears.

30-second answer

init creates the controller and stores its dependencies; the view doesn't exist yet. viewDidLoad runs once after the view and outlets are loaded, so view setup goes there. Touching view in init forces it to load early, which defeats lazy loading and can run setup before dependencies are set.

Practise saying it · 30 s. No recording, just a timer

Explain init vs viewDidLoad.

Say your answer out loud, then check which of these points you covered:

  • init stores dependencies
  • viewDidLoad sets up views
  • Outlets nil before load

Deep dive

Inject dependencies in init; configure views in viewDidLoad.

Outlets are nil until the view loads.

loadViewIfNeeded() forces loading, which is handy in tests.

Override loadView only to supply a custom root view.

Common mistakes

  • Configuring outlets in init.
  • Accessing view in init.

Senior take & follow-ups

Seniors separate dependencies (init) from view setup (viewDidLoad).

Follow-up questions

Think of your answer first, then open the hint.

  1. When do you override loadView?

    Show hint

    To set a custom root view without a storyboard.

  2. How do you test a view controller's views?

    Show hint

    Call loadViewIfNeeded() first.

Suggest a fix if something here is wrong or out of date.