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 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 }
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:
Nachteile:
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:
Nachteile: