ProgrammierungiOS Entwickler

Wie funktionieren failable Initialisierer (`init?`) in Swift? Wann und warum sollten sie verwendet werden, welche wichtigen Nuancen sind zu beachten?

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

Antwort

Failable Initialisierer (init?) in Swift ermöglichen es, eine Situation zu beschreiben, in der die Erstellung einer Instanz eines Typs fehlschlagen kann und nil zurückgegeben wird. Sie werden häufig zur Validierung von Eingabedaten oder Transformationen verwendet, die möglicherweise nicht erfolgreich sind. In einem failable Initialisierer kann man explizit nil zurückgeben, um anzuzeigen, dass die Erstellung des Objekts gescheitert ist.

Beispiel:

struct User { let name: String let age: Int init?(name: String, age: Int) { guard !name.isEmpty, age > 0 else { return nil } self.name = name self.age = age } }

So kann man die Erstellung von ungültigen Objekten verhindern.

Wichtige Nuancen:

  • In einer Vererbungskette können failable Initialisierer nur von failable Initialisierern überschrieben werden.
  • Bei der Verwendung einer Struktur mit failable Initialisierer in einem Array, in dem die Initialisierung durch Mappen erfolgt (compactMap), ist dies praktisch zur Filterung ungültiger Instanzen.

Fangfrage

Frage: Was ist der Unterschied zwischen init? und init! und wann sollte man einen failable Initialisierer mit impliziter Entpackung verwenden?

Antwort: init? gibt ein Optional (<type?>) zurück, und wenn die Initialisierung fehlschlägt, wird nil zurückgegeben, was eine sichere Behandlung erfordert. init! gibt ein implicitly unwrapped optional (<type!>) zurück, und wenn die Initialisierung fehlschlägt, wird ebenfalls nil zurückgegeben, aber die Verwendung eines solchen Objekts ohne Prüfung führt zu einem Runtime-Crash. Verwenden Sie init! nur, wenn Sie sich sicher sind, dass die Initialisierung in Ihrem Kontext nicht fehlschlagen kann (zum Beispiel bei der Arbeit mit Storyboards in UIKit).

let value = Int("abc") // value wird nil sein

Beispiele für reale Fehler aufgrund fehlender Kenntnisse über die Feinheiten des Themas.


Geschichte

Beim manuellen Parsen von JSON wurde ein gewöhnlicher Initialisierer anstelle eines failable verwendet. Dies führte zur Erstellung "leerer" Benutzer, da die Validierung fehlte und die Anwendung ungültige Daten nicht filterte.


Geschichte

Die Verwendung von init! mit potenziell ungültigen Daten führte zu einem Absturz der Anwendung nach einer API-Aktualisierung: Das Format der Eingabedaten hatte sich geändert, und bei der Entpackung des Objekts trat eine Laufzeitausnahme aufgrund der impliziten Entpackung von nil auf.


Geschichte

Bei einer benutzerdefinierten Implementierung von failable init wurde vergessen, nil explizit für bestimmte Szenarien zurückzugeben, und letztlich wurde die Struktur mit "schmutzigen" Feldern initialisiert, was später zu Bugs in der Geschäftslogik führte.