ProgrammatieiOS ontwikkelaar

Beschrijf de levenscyclus van een view controller in UIKit, en hoe onjuiste omgang met de levenscyclus kan leiden tot geheugenlekken of bugs in de UI. Welke punten moet je weten?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

De levenscyclus van UIViewController omvat de volgende belangrijke methoden:

  • init(nibName:bundle:) / init(coder:): initialisatie
  • loadView: creëren van de view-hiërarchie
  • viewDidLoad: view is geladen (ideale plek voor initiële opstelling)
  • viewWillAppear / viewDidAppear: view verschijnt/verschenen
  • viewWillDisappear / viewDidDisappear: view verdwijnt/verdwenen
  • deinit: verwijderen van de controller

De volgorde van aanroepen van de methoden:

  • Eerst wordt de view-hiërarchie gecreëerd (loadView, dan viewDidLoad)
  • Bij elk scherm verschijnen en verdwijnen worden viewWillAppear/viewWillDisappear aangeroepen, daarna viewDidAppear/viewDidDisappear
  • Na verwijdering — deinit

Punten:

  • In viewDidLoad moet je geen toegang vragen tot de afmetingen van de view — deze kunnen niet actueel zijn
  • Het is belangrijk om middelen vrij te geven (waarnemers, timers) in deinit of viewWillDisappear
  • Voeg subviews toe in viewDidLoad, maar niet in viewWillAppear — anders kan duplicatie optreden bij elke verschijning

Voorbeeld:

class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupViews() setupBindings() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Abonneren op meldingen } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Afmelden van meldingen } deinit { // Opruimen } }

Vrag van misleiding

Vraag:

Is het toegestaan voor een view controller om toegang te krijgen tot de eigenschappen van de view buiten de levenscyclus (bijvoorbeeld in de initializer)?

Antwoord: Nee, tot het moment van aanroep (of overschrijving) van loadView kunnen alle eigenschappen die verband houden met de view niet geïnitialiseerd zijn. Elke toegang daartoe buiten loadView/viewDidLoad leidt tot een crash.

Voorbeeld:

// Fout: self.view is nog niet geïnitialiseerd! init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = .red // CRASH }

Voorbeelden van echte fouten door het niet kennen van de nuances van het onderwerp


Verhaal

Het project crashtte door voortijdige toegang tot self.view in init — de view was niet aangemaakt, wat leidde tot een crash.


Verhaal

In grote projecten vergaten ze zich af te melden bij NotificationCenter of delegate in viewWillDisappear en/of deinit, wat leidde tot geheugenlekken (NotificationCenter bleef verwijzen naar de view controller, deze werd niet vrijgegeven en bleef gebeurtenissen afhandelen).


Verhaal

In viewWillAppear werden bij elke verschijning nieuwe subviews aan de view toegevoegd (bijvoorbeeld een laadindicator), zonder het bestaan te controleren. Hierdoor verschenen er steeds meer dubbele indicatoren bij elke terugkeer naar het scherm, wat de UI verstoorde.