ProgrammingiOS Developer

Describe the lifecycle of a view controller in UIKit, and how improper handling of the lifecycle can lead to memory leaks or UI bugs. What nuances should be known?

Pass interviews with Hintsage AI assistant

Answer

The lifecycle of UIViewController includes key methods:

  • init(nibName:bundle:) / init(coder:): initialization
  • loadView: create view hierarchy
  • viewDidLoad: view is loaded (ideal place for initial setup)
  • viewWillAppear / viewDidAppear: view is about to/has appeared
  • viewWillDisappear / viewDidDisappear: view is about to/disappeared
  • deinit: controller removal

Order of method calls:

  • First, the view hierarchy is created (loadView, then viewDidLoad)
  • On each appearance and disappearance on screen, viewWillAppear/viewWillDisappear are called, followed by viewDidAppear/viewDidDisappear
  • After removal — deinit

Nuances:

  • Avoid accessing view sizes in viewDidLoad — they might not be valid
  • It’s important to release resources (observers, timers) in deinit or viewWillDisappear
  • Add subviews in viewDidLoad, but not in viewWillAppear — otherwise, duplications may occur with each appearance

Example:

class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupViews() setupBindings() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Subscribe to notifications } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Unsubscribe from notifications } deinit { // Clean up } }

Trick Question

Question:

Is it acceptable for a view controller to access properties of the view outside of the lifecycle (e.g., in the initializer)?

Answer: No, until loadView is called (or overridden), all properties related to the view may be uninitialized. Any access to them outside of loadView/viewDidLoad will lead to a crash.

Example:

// Error: self.view is not initialized yet! init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = .red //CRASH }

Examples of Real Errors Due to Ignorance of Topic Nuances


Story

The project crashed due to premature access to self.view in init — the view was not created, leading to a crash.


Story

In large projects, forgetting to unsubscribe from NotificationCenter or delegate in viewWillDisappear and/or deinit led to memory leaks (NotificationCenter referenced the view controller, which was not released and continued to listen to events).


Story

In viewWillAppear, new subviews were added to the view each time it appeared (for example, showing a loading indicator) without checking for existence. As a result, more and more duplicate indicators appeared each time returning to the screen, causing the UI to malfunction.