ProgrammierungSwift-Programmierer

Was ist 'defer' in Swift? Wie funktioniert es und wofür wird es verwendet, welche untypischen Anwendungsszenarien gibt es?

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

Antwort.

Der Operator defer verzögert die Ausführung von Code bis zum Verlassen des aktuellen Geltungsbereichs, normalerweise aus einer Funktion. Er ist nützlich für die Bereinigung von Ressourcen, das Schließen von Dateien und die Freigabe von Speicher – die sogenannte automatisierte Bereinigung.

Eigenschaften:

  • Defer-Blöcke werden in umgekehrter Reihenfolge ihrer Deklaration ausgeführt (LIFO).
  • Der Aufruf erfolgt immer – sowohl beim normalen Verlassen der Funktion als auch beim Werfen eines Fehlers.
  • Vermeidet die Duplizierung von Bereinigungscode und unterstützt eine saubere Architektur von Funktionen.

Beispiel:

func processFile() { let file = openFile() defer { closeFile(file) } // Arbeiten mit der Datei // Die Datei wird selbst im Falle von throw oder return geschlossen }

Ungewöhnliche Anwendungen: teilweise Imitation von 'finally'-Konstrukten, Gruppierung von Code für Logging und zur Verfolgung von Ausführungszeiten.

Fangfrage.

Wird defer ausgeführt, wenn die Anwendung während der Ausführung der Funktion beendet wird?

— Nein. Defer wird nur bei einem normalen Abschluss des Geltungsbereichs (return, throw oder normaler Ausgang) ausgeführt. Wenn die Anwendung unerwartet beendet wird (z. B. aufgrund des Signals SIGKILL oder fatalError), haben die Defer-Blöcke keine Zeit, ausgeführt zu werden.

Beispiel:

func foo() { defer { print("Cleanup") } fatalError("Crash!") // defer wird nicht ausgeführt }

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


Geschichte

Eine Funktion, die mit Sockets arbeitete, reinigte die Verbindung im Falle eines throw nicht. Daten blieben hängen, Verbindungen wurden nicht freigegeben. Nach der Einführung von defer funktionierte alles korrekt: Ressourcen wurden immer geschlossen.


Geschichte

Ein Entwickler versuchte, sich auf defer zur Freigabe eines globalen Zustands zu verlassen. Bei einem fatalError wurde die Ressource nicht freigegeben, was zu Blockierungen der Dienste und der Notwendigkeit eines Neustarts führte.


Geschichte

In einer Funktion wurden mehrere Defer-Deklarationen gemacht, in der Annahme, dass sie in der Reihenfolge ihrer Deklaration ausgeführt würden. Infolgedessen wurden Ressourcen in der falschen Reihenfolge geschlossen (z. B. wurde zuerst der Datei-Deskriptor geschlossen, und dann wurde versucht, darauf zuzugreifen). Lösung: sich an die LIFO-Reihenfolge der Ausführung von Defer-Blöcken erinnern.