Do-Catch: Was es ist, Konstrukt und Fehlerbehandlung in Swift

Autor: IT Sectr Veröffentlicht: 2026-05-26 Lesezeit: 8 Min.

Do-Catch ist ein Sprachkonstrukt in Swift zur Fehlerbehandlung, das Ausnahmen abfängt, die über throw ausgelöst wurden, und den entsprechenden Codeblock ausführt. Im Gegensatz zu traditionellem try-catch in anderen Sprachen erfordert Swift eine explizite Markierung von Funktionen, die einen Fehler auslösen können, mit dem Modifikator throws. Laut Swift.org, 2026 ist Do-Catch der primäre Fehlerbehandlungsmechanismus in Swift und bietet Typsicherheit.

Kernpunkte

  • Do-Catch ist ein Swift-Konstrukt, das Fehler aus Blöcken mit try und throw abfängt.
  • throws ist ein Funktionsmarker, der angibt, dass sie einen Fehler auslösen kann.
  • try ist das Schlüsselwort zum Aufrufen einer throwing-Funktion innerhalb eines do-Blocks.
  • catch ist der Fehlerbehandlungsblock mit Typmustervergleich.
  • try? und try! sind alternative Formen, die Fehler in nil umwandeln oder einen Crash verursachen.

Was ist Do-Catch?

Do-Catch ist ein Konstrukt in Swift, das aus einem do-Block, in dem Code ausgeführt wird, der einen Fehler auslösen kann, und einem oder mehreren catch-Blöcken besteht, die diesen Fehler behandeln. Der do-Block enthält Aufrufe von throwing-Funktionen, die mit try markiert sind, und catch-Blöcke gleichen den Fehler nach Typ ab.

Swift implementiert ein Modell der strukturierten Fehlerbehandlung, das sich von Ausnahmen in Objective-C unterscheidet. Hier ist ein Fehler kein Exception mit Stack-Entwicklung, sondern ein Wert, der dem Error-Protokoll entspricht. Das Auslösen eines Fehlers über throw überträgt die Kontrolle an den nächsten catch-Block ohne den Overhead der Stack-Entwicklung.

Ein Schlüsselmerkmal von Swift ist die explizite Behandlung. Der Compiler erlaubt nicht, eine throwing-Funktion ohne try, do-catch oder einen alternativen Mechanismus (try?, try!) aufzurufen. Dies schließt Situationen aus, in denen ein Fehler unbemerkt bleibt.

Fehlermodell in Swift: Error-Protokoll und throwing-Funktionen

Im Zentrum der Fehlerbehandlung in Swift steht das Error-Protokoll. Jeder Typ, der diesem Protokoll entspricht, kann über throw ausgelöst werden. Fehler werden typischerweise als Enum definiert, das Error entspricht.

Error-Protokoll

Error ist ein leeres (Marker-)Protokoll. Es erfordert keine Methodenimplementierung, nur Konformität. Der Swift-Compiler verwendet Error für die statische Überprüfung: Eine Funktion mit throws kann nur einen Wert auslösen, der Error entspricht.

Throwing-Funktionen

Eine mit throws markierte Funktion muss mit try aufgerufen werden. Wenn innerhalb einer solchen Funktion ein throw auftritt, wird die Kontrolle an den aufrufenden do-catch übertragen. Wenn der Fehler nirgendwo in der Aufrufkette behandelt wird, propagiert er auf die nächsthöhere Ebene.

swift
enum FileError: Error {
    case notFound
    case permissionDenied
    case corrupted(String)
}

func readFile(path: String) throws -> String {
    guard FileManager.default.fileExists(atPath: path) else {
        throw FileError.notFound
    }
    return try String(contentsOfFile: path)
}

Rethrows

rethrows ist ein Modifikator für Funktionen, die einen throwing-Closure als Parameter akzeptieren. Wenn der übergebene Closure keinen Fehler auslöst, kann die rethrows-Funktion ohne try aufgerufen werden. Dies ermöglicht das Schreiben generischer Funktionen höherer Ordnung, die sowohl mit throwing- als auch mit nicht-throwing-Closures kompatibel sind.

Do-Catch-Syntax: Mehrere catch-Blöcke

Swift unterstützt mehrere catch-Blöcke mit typbasierter Fehlerzuordnung. Dies ähnelt when in Kotlin oder einem typorientierten switch: Der erste passende catch wird ausgeführt, die restlichen werden übersprungen.

Typzuordnung

Jeder catch-Block kann ein Muster enthalten, das einem bestimmten Fehlertyp entspricht. Swift überprüft die Blöcke der Reihe nach, daher sollten spezifischere Typen vor allgemeineren kommen. Wenn kein Muster passt, wird der catch-Block ohne Muster ausgeführt.

Behandlung mehrerer Typen

Die Typsicherheit von Do-Catch ermöglicht es, jeden Fehler separat zu behandeln oder mehrere Typen in einem Block durch Komma-getrennten Mustervergleich zu kombinieren. Dies beseitigt umständliche if-else-Ketten, die für Objective-C typisch sind, wo die Fehleranalyse über Rückgabecodes oder NSError mit Domain- und Code-Prüfung erfolgte.

Swift unterstützt auch catch where — Zuordnung mit zusätzlicher Bedingung. Zum Beispiel kann man Fehler nach einem bestimmten Code oder Text filtern: catch URLError where error.code == .notConnectedToInternet. Dies reduziert die Anzahl der catch-Blöcke bei gleichbleibender Präzision.

Zum Debuggen von throwing-Funktionen bietet Swift eine Unterscheidung zwischen Fehlern und Ausnahmen. Ein Swift-Fehler ist ein Rückgabewert, der keine Stack-Entwicklung erfordert. Objective-C-Ausnahmen (@try/@catch) arbeiten auf Runtime-Ebene und werden nur für fatale Fehler verwendet. Do-Catch behandelt Fehler, nicht Ausnahmen, was es vorhersagbar und leistungsfähig macht.

Bei der Entwicklung von Bibliotheken und SDKs ist es wichtig zu bedenken, dass throwing-Funktionen Teil des öffentlichen Vertrags sind. Der Fehlertyp ist nicht in der Signatur spezifiziert, daher dokumentieren Sie, welche Fehler eine Funktion auslösen kann, in Kommentaren oder über Result-ähnliche Enums. Dies hilft API-Benutzern, korrekte catch-Blöcke zu schreiben, ohne in die Implementierung schauen zu müssen.

Im Kontext der asynchronen Programmierung löst Do-Catch mit async/await das Problem des Callback-Hell. Früher erforderte die Fehlerbehandlung in asynchronem Code in Swift verschachtelte Closures mit Error?-Prüfung in Completion-Handlern. Mit async/await und Do-Catch sieht asynchroner throwing-Code wie synchroner Code aus, was das Lesen und Warten komplexer Anforderungsketten mit Fehlerbehandlung bei jedem Schritt vereinfacht.

swift
do {
    let content = try readFile(path: "/data/config.json")
    process(content)
} catch FileError.notFound {
    createDefaultConfig()
} catch FileError.permissionDenied {
    requestAccess()
} catch FileError.corrupted(let detail) {
    logCorruption(detail)
} catch {
    print("Unbekannter Fehler: \(error)")
}

Try-Varianten: try, try?, try! und wann man sie verwendet

Swift bietet drei Möglichkeiten, throwing-Funktionen aufzurufen: try, try? und try!. Jede Option löst eine bestimmte Aufgabe und hat ihre Grenzen.

try — Standardaufruf

try wird innerhalb eines do-Blocks verwendet, und der Fehler wird in catch behandelt. Dies ist die primäre Art, throwing-Funktionen aufzurufen. Der Compiler verlangt, dass try sich in einem Kontext befindet, in dem der Fehler abgefangen werden kann.

try? — Umwandlung in Optional

try? wandelt das Ergebnis einer throwing-Funktion in ein Optional um. Wenn die Funktion einen Fehler auslöst, gibt try? nil zurück, andernfalls ein Optional mit dem erfolgreichen Wert. Nützlich für Aufrufe, bei denen der Fehler ignoriert werden kann, aber ein Erfolgsindikator benötigt wird.

try! — Erzwungene Ausführung

try! unterdrückt die Fehlerbehandlung. Wenn die throwing-Funktion einen Fehler auslöst, wird die App mit einem Laufzeitfehler beendet. Verwenden Sie try! nur, wenn Sie absolut sicher sind, dass der Fehler unmöglich ist — zum Beispiel beim Laden einer gebündelten Ressource.

swift
// try? — Fehler ignorieren, nil bei Fehlschlag erhalten
if let data = try? Data(contentsOf: url) {
    processData(data)
}

// try! — nur wenn der Fehler garantiert unmöglich ist
let bundled = try! String(contentsOfFile: "Assets/default.txt")

// try — Standardoption in do-catch
do {
    let result = try performNetworkRequest()
    updateUI(result)
} catch {
    showError(error)
}

Do-Catch in der iOS-Entwicklung: Praxisbeispiele

Do-Catch wird in der iOS-Entwicklung aktiv für die Arbeit mit System-APIs verwendet. Betrachten wir typische Szenarien: Arbeit mit dem Dateisystem, Core Data und Netzwerkanfragen.

Dateisystem

Viele Methoden von FileManager sind throwing. Do-Catch ermöglicht die korrekte Behandlung von fehlenden Dateien, Ressourcenbelegung oder unzureichenden Berechtigungen.

Netzwerkanfragen mit Codable

Das Parsen von JSON über JSONDecoder ist eine throwing-Operation. Do-Catch fängt Dekodierungsfehler und Netzwerkausfälle separat ab und liefert dem Benutzer eine genaue Fehlermeldung.

swift
struct User: Codable {
    let id: Int
    let name: String
}

func fetchUser(id: Int) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Aufruf mit Behandlung
do {
    let user = try await fetchUser(id: 42)
    showUser(user)
} catch let error as URLError {
    showNetworkAlert(error)
} catch let error as DecodingError {
    showParseError(error)
} catch {
    showGenericError(error)
}

Häufige Fehler mit Do-Catch

Entwickler, insbesondere solche, die von anderen Sprachen kommen, machen oft charakteristische Fehler bei der Verwendung von Do-Catch. Betrachten wir die häufigsten.

  • Vergessenes try — Das Aufrufen einer throwing-Funktion ohne try führt zu einem Kompilierungsfehler. Swift erlaubt nicht, Fehler implizit zu ignorieren.
  • Leerer catch — Ein catch-Block ohne Behandlung verbirgt den Fehler. Protokollieren oder behandeln Sie den Fehler immer, auch wenn er unmöglich erscheint.
  • Catch ohne Zuordnung — Ein einzelner generischer catch für alle Fehler verliert die Vorteile der Typsicherheit. Trennen Sie die Behandlung nach Typen durch mehrere Blöcke.
  • Übermäßige Verwendung von try! — try! in Produktionscode ist eine Quelle unerwarteter Abstürze. Verwenden Sie es nur für gebündelte Ressourcen oder Tests.

Häufig gestellte Fragen

Wie unterscheidet sich Do-Catch in Swift von try-catch in anderen Sprachen?

In Swift ist ein Fehler ein Wert, der dem Error-Protokoll entspricht, keine Ausnahme mit Stack-Entwicklung. Throwing-Funktionen müssen explizit mit throws markiert werden, und der Compiler verlangt try beim Aufruf — dies schließt unbehandelte Fehler zur Kompilierungszeit aus.

Kann Do-Catch mit async/await verwendet werden?

Ja, async-Funktionen können auch throws sein, und do-catch funktioniert mit ihnen. Der Aufruf einer asynchronen throwing-Funktion erfordert try await innerhalb eines do-Blocks. Dies ist die Standardmethode zur Fehlerbehandlung in asynchronem Swift-Code.

Wie behandelt man einen Fehler ohne do-catch?

Es gibt Alternativen: try? wandelt den Fehler in nil um, try! verursacht bei Fehler einen Crash, und rethrows ermöglicht die Weitergabe eines Fehlers aus einem Closure. Do-catch bleibt die primäre Methode der expliziten Behandlung.

Kann eine Funktion verschiedene Fehlertypen auslösen?

Swift typisiert die ausgelösten Fehler nicht — jede throwing-Funktion kann jeden Typ auslösen, der Error entspricht. Trennen Sie die Behandlung durch Zuordnung in catch nach spezifischen Fehlertypen.

Sollte ich alle Fehler in einen benutzerdefinierten Typ verpacken?

Ja, das ist eine bewährte Praxis. Definieren Sie AppError als Enum, das Error entspricht, und konvertieren Sie Systemfehler in Domänenfehler. Dies vereinheitlicht die Behandlung und isoliert die Anwendungsschicht von Systemdetails.

Zusammenfassung

  • Do-Catch ist ein Swift-Konstrukt zur Fehlerbehandlung mit obligatorischer throws-Markierung an Funktionen und try bei Aufrufen.
  • Swift-Fehler sind Werte, die dem Error-Protokoll entsprechen, keine Ausnahmen mit Stack-Entwicklung, was bei ausbleibendem Fehler keinen Overhead verursacht.
  • Mehrere catch-Blöcke ermöglichen die separate Behandlung verschiedener Fehlertypen mit Mustervergleich ähnlich switch.
  • try? wandelt einen Fehler für einfache Szenarien in nil um, try! ist ein erzwungener Aufruf mit Absturzrisiko, der nur für garantierte Erfolgsoperationen verwendet wird.
  • Do-Catch mit async/await ist die Standardmethode zur Fehlerbehandlung in asynchronem Swift-Code mit try await.
  • Vermeiden Sie leere catch-Blöcke und übermäßige Verwendung von try! — dies verbirgt Fehler und führt zu unerwarteten Abstürzen in der Produktion.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch