ProgrammierungiOS/Swift Entwickler

Was sind Defer-Anweisungen in Swift? Was sind die Besonderheiten ihrer Ausführung, wo sind sie sinnvoll und mit welchen Fallstricken kann man konfrontiert werden?

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

Antwort.

Geschichte der Frage:

Defer wurde in Swift (inspiriert von Analoga in Go, C#) hinzugefügt, um die garantierte Bereinigung von Ressourcen selbst im Falle von Fehlern, beim Verlassen einer Funktion oder beim Rückgeben von Werten aus verschiedenen Punkten der Funktionen zu gewährleisten.

Problem:

Vorzeitige Freigabe, vergessene Bereinigungen von Ressourcen (z. B. Schließen von Dateien, Protokollierung, Rollback von Transaktionen). Manchmal wird die Reihenfolge der Ausführung verwechselt, wenn fälschlicherweise angenommen wird, dass Defer zum Zeitpunkt der Deklaration ausgeführt wird.

Lösung:

Defer ist ein spezieller Block, der die Ausführung von Code bis zum Ende des aktuellen Gültigkeitsbereichs (Scope), normalerweise einer Funktion, aufschiebt. Alle Defer werden in umgekehrter Reihenfolge ihrer Platzierung ausgeführt (LIFO). Dies ermöglicht eine zentrale Verwaltung der Bereinigung von Ressourcen, der Freigabe von Speicher oder des Rollbacks von Transaktionen.

Beispielcode:

func processFile() { let file = File("/tmp/data.txt") file.open() defer { file.close() print("Datei geschlossen") } // Arbeiten mit der Datei print("Daten lesen…") }

Wichtige Merkmale:

  • Wird immer bei jedem Verlassen des Scopes ausgeführt, selbst bei Fehlern und vorzeitigem Return.
  • Mehrere Defer werden in umgekehrter Reihenfolge ausgeführt.
  • Kann in jedem Gültigkeitsbereich verwendet werden, nicht nur in Funktionen.

Fangfragen.

Wird der Code innerhalb von Defer ausgeführt, wenn die Anwendung (crash) vor dem Verlassen der Funktion abstürzt?

Nein, der Defer-Code wird nur bei korrektem Verlassen des Gültigkeitsbereichs ausgeführt. Wenn die Anwendung abrupt beendet wird (z. B. fatal error), wird Defer nicht ausgeführt.

Kann man return innerhalb von Defer verwenden?

Nein, das kann man nicht. Der Defer-Block erlaubt keine Rückgaben oder das Beenden des Gültigkeitsbereichs, nur Anweisungen.

Kann Defer zur Modifikation von Variablen, die vor Defer deklariert wurden, verwendet werden?

Ja, Defer erfasst Werte vom aktuellen Stack zum Zeitpunkt der Ausführung. Man kann Werte ändern, die vor Defer deklariert wurden, und sie bleiben beim Verlassen des Scopes erhalten.

Beispielcode:

func example() -> Int { var result = 0 defer { result = 42 } return result // Defer wird ausgeführt, das Ergebnis ist 42 }

Typische Fehler und Anti-Patterns

  • Falsche Erwartung, dass Defer sofort nach der Deklaration ausgeführt wird.
  • Verwendung von Defer außerhalb von Scopes, wo es keinen Sinn macht.
  • Schwerwiegende Operationen innerhalb von Defer belassen.

Beispiel aus dem Leben

Negativer Fall

Die Datei wird geöffnet, aber nur am Ende der Funktion explizit geschlossen, und bei Fehlern oder vorzeitigem Verlassen der Funktion bleibt die Datei geöffnet.

Vorteile:

  • Einfache Implementierung

Nachteile:

  • Datei wird bei Fehlern nicht geschlossen
  • Ressourcenleck

Positiver Fall

Verwendung von Defer zum Schließen der Datei sofort nach dem Öffnen. Selbst wenn eine Ausnahme auftritt oder die Funktion vorzeitig verlassen wird, wird die Datei garantierten geschlossen.

Vorteile:

  • Sicher, keine Lecks
  • Sauberer und vorhersehbarer Code

Nachteile:

  • Vorsicht im Umgang mit veränderbaren Ressourcen innerhalb von Defer