ProgrammierungiOS-Entwickler

Beschreiben Sie den Lebenszyklus eines ViewControllers in UIKit und wie unsachgemäße Handhabung des Lebenszyklus zu Speicherlecks oder UI-Fehlern führen kann. Welche Feinheiten sollten bekannt sein?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

Der Lebenszyklus eines UIViewController umfasst die wichtigsten Methoden:

  • init(nibName:bundle:) / init(coder:): Initialisierung
  • loadView: Erstellung der View-Hierarchie
  • viewDidLoad: View wurde geladen (idealer Ort für die Erstkonfiguration)
  • viewWillAppear / viewDidAppear: View wird angezeigt / wurde angezeigt
  • viewWillDisappear / viewDidDisappear: View wird ausgeblendet / wurde ausgeblendet
  • deinit: Entfernung des Controllers

Reihenfolge der Methodenaufrufe:

  • Zuerst wird die View-Hierarchie erstellt (loadView, dann viewDidLoad)
  • Bei jedem Erscheinen und Ausblenden werden viewWillAppear / viewWillDisappear, dann viewDidAppear / viewDidDisappear aufgerufen
  • Nach der Entfernung — deinit

Feinheiten:

  • In viewDidLoad sollte nicht auf die Größen der View zugegriffen werden — diese könnten nicht aktuell sein
  • Es ist wichtig, Ressourcen (Beobachter, Timer) in deinit oder viewWillDisappear freizugeben
  • Subviews sollten in viewDidLoad hinzugefügt werden, aber nicht in viewWillAppear — sonst kann es bei jedem Auftauchen zu Duplikationen kommen

Beispiel:

class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupViews() setupBindings() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Für Benachrichtigungen abonnieren } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Von Benachrichtigungen abmelden } deinit { // Aufräumen } }

Fangfrage

Frage:

Darf der ViewController außerhalb des Lebenszyklus auf Eigenschaften der View zugreifen (zum Beispiel im Initialisierer)?

Antwort: Nein, vor dem Aufruf (oder der Überschreibung) von loadView können alle mit der View verbundenen Eigenschaften nicht initialisiert sein. Jeder Zugriff auf sie außerhalb von loadView / viewDidLoad führt zu einem Crash.

Beispiel:

// Fehler: self.view ist noch nicht initialisiert! init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = .red //CRASH }

Beispiele für reale Fehler aufgrund mangelnden Wissens über die Feinheiten des Themas


Geschichte

Das Projekt stürzte ab, weil auf self.view im Init zu früh zugegriffen wurde – die View war nicht erstellt, was zu einem Crash führte.


Geschichte

In großen Projekten wurde vergessen, sich in viewWillDisappear und/oder deinit vom NotificationCenter oder Delegate abzumelden, was zu Speicherlecks führte (NotificationCenter verwies auf den ViewController, dieser wurde nicht freigegeben und hörte weiterhin Ereignisse).


Geschichte

In viewWillAppear wurden bei jedem Erscheinen neue Subviews zur View hinzugefügt (zum Beispiel wurde ein Ladeindikator angezeigt), ohne auf deren Existenz zu prüfen. Infolgedessen erschienen bei jedem Zurückkehren immer mehr duplizierte Indikatoren, die UI fiel aus.