Do-Catch — de Swift-taalconstructie voor foutafhandeling die uitzonderingen opvangt die via throw worden gegenereerd en het bijbehorende codeblok uitvoert. In tegenstelling tot traditionele try-catch in andere talen, vereist Swift dat functies die een fout kunnen gooien expliciet worden gemarkeerd met de modifier throws. Volgens Swift.org, 2026 is Do-Catch het primaire mechanisme voor foutafhandeling in Swift, dat typeveiligheid biedt.
Belangrijkste punten
Do-Catch — is een constructie in Swift bestaande uit een do-blok, waarbinnen code wordt uitgevoerd die een fout kan gooien, en een of meer catch-blokken die deze fout afhandelen. Het do-blok bevat aanroepen van throwing-functies gemarkeerd met try, en de catch-blokken matchen de fout op type.
Swift implementeert een model van gestructureerde foutafhandeling, anders dan uitzonderingen in Objective-C. Hier is een fout geen exception met stack-ontwikkeling, maar een waarde die voldoet aan het Error-protocol. Het gooien van een fout via throw draagt controle over aan het dichtstbijzijnde catch-blok zonder overhead van stack-ontwikkeling.
Een belangrijk kenmerk van Swift — explicietheid van afhandeling. De compiler staat niet toe een throwing-functie aan te roepen zonder try, do-catch of een alternatief mechanisme (try?, try!). Dit elimineert situaties waarin een fout onopgemerkt blijft.
De basis van foutafhandeling in Swift is het Error-protocol. Elk type dat aan dit protocol voldoet, kan via throw worden gegooid. Meestal worden fouten gedefinieerd als een enum met Error-bevestiging.
Error — een leeg protocol (marker). Het vereist geen implementatie van methoden, alleen bevestiging van conformiteit. De Swift-compiler gebruikt Error voor statische controle: een functie met throws kan alleen een waarde gooien die aan Error voldoet.
Een functie gemarkeerd met throws moet worden aangeroepen met try. Als binnen zo'n functie een throw plaatsvindt, wordt controle overgedragen aan de aanroepende do-catch. Als de fout nergens in de aanroepketen wordt afgehandeld, wordt deze doorgegeven aan een hoger niveau.
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 — een modifier voor functies die een throwing-closure als parameter accepteren. Als de doorgegeven closure geen fout gooit, kan de rethrows-functie zonder try worden aangeroepen. Dit maakt het mogelijk generieke hogere-orde functies te schrijven die compatibel zijn met throwing en non-throwing closures.
Swift ondersteunt meerdere catch-blokken met matching op fouttype. Dit lijkt op when in Kotlin of switch op type: de eerste overeenkomende catch wordt uitgevoerd, de rest wordt overgeslagen.
Elk catch-blok kan een matchpatroon bevatten voor een specifiek fouttype. Swift controleert de blokken op volgorde, dus specifiekere typen moeten voor algemenere komen. Als geen patroon overeenkomt, wordt het catch-blok zonder patroon uitgevoerd.
Typeveiligheid van Do-Catch maakt het mogelijk elke fout afzonderlijk te behandelen of meerdere typen in één blok te combineren via komma's in pattern-matching. Dit elimineert omslachtige if-else-ketens die kenmerkend zijn voor Objective-C, waar foutanalyse gebeurde via retourcode of NSError met controle van domain en code.
Swift ondersteunt ook catch where — matching met een extra voorwaarde. Men kan bijvoorbeeld fouten filteren op specifieke code of tekst: catch URLError where error.code == .notConnectedToInternet. Dit vermindert het aantal catch-blokken terwijl de precisie van afhandeling behouden blijft.
Voor het debuggen van throwing-functies biedt Swift het verschil tussen fouten en uitzonderingen. Een Swift-fout is een geretourneerde waarde die geen stack-ontwikkeling vereist. Objective-C-uitzonderingen (@try/@catch) werken op run-time-niveau en worden alleen gebruikt voor fatale fouten. Do-Catch handelt precies fouten af, niet uitzonderingen, wat het voorspelbaar en performant maakt.
Bij het ontwikkelen van bibliotheken en SDK's is het belangrijk te onthouden dat throwing-functies deel uitmaken van het publieke contract. Het fouttype is niet gespecificeerd in de handtekening, dus documenteer welke fouten de functie kan gooien in een opmerking of via een Result-achtige enum. Dit helpt API-gebruikers correcte catch-blokken te schrijven zonder in de implementatie te kijken.
In de context van asynchroon programmeren lost Do-Catch met async/await het callback hell-probleem op. Voorheen vereiste foutafhandeling in asynchrone Swift-code geneste closures met Error?-controle in de completion handler. Met async/await en Do-Catch ziet asynchrone throwing-code eruit als synchrone code, wat het lezen en onderhouden van complexe aanvraagketens met foutafhandeling bij elke stap vereenvoudigt.
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("Onbekende fout: \(error)")
}
Swift biedt drie varianten voor het aanroepen van throwing-functies: try, try? en try!. Elke variant lost een specifieke taak op en heeft zijn beperkingen.
try wordt gebruikt binnen een do-blok en de fout wordt afgehandeld in catch. Dit is de primaire manier om throwing-functies aan te roepen. De compiler vereist dat try zich in een context bevindt waar de fout kan worden opgevangen.
try? converteert het resultaat van een throwing-functie naar Optional. Als de functie een fout gooit, retourneert try? nil, anders — Optional met de succeswaarde. Handig voor aanroepen waar de fout kan worden genegeerd, maar een succesindicator nodig is.
try! onderdrukt foutafhandeling. Als de throwing-functie een fout gooit, wordt de applicatie beëindigd met een runtime-fout. Gebruik try! alleen wanneer u absoluut zeker bent dat de fout onmogelijk is — bijvoorbeeld bij het laden van een ingebedde resource.
// try? — negeren de fout, krijgen nil bij storing
if let data = try? Data(contentsOf: url) {
processData(data)
}
// try! — alleen als de fout gegarandeerd onmogelijk is
let bundled = try! String(contentsOfFile: "Assets/default.txt")
// try — standaard optie in do-catch
do {
let result = try performNetworkRequest()
updateUI(result)
} catch {
showError(error)
}
Do-Catch wordt actief gebruikt in iOS-ontwikkeling voor het werken met systeem-API's. Laten we typische scenario's bekijken: werken met het bestandssysteem, Core Data en netwerkverzoeken.
Veel methoden van FileManager zijn throwing. Do-Catch maakt het mogelijk ontbrekende bestanden, bezette resources of ontoereikende rechten correct af te handelen.
JSON-parsen via JSONDecoder is een throwing-bewerking. Do-Catch vangt decodeerfouten en netwerkstoringen afzonderlijk op en biedt de gebruiker de exacte fouttekst.
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)
}
// Aanroep met afhandeling
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)
}
Ontwikkelaars, vooral degenen die overstappen van andere talen, maken vaak karakteristieke fouten bij het gebruik van Do-Catch. Laten we de meest voorkomende bekijken.
Veelgestelde vragen
In Swift is een fout een waarde die voldoet aan het Error-protocol, geen exception met stack-ontwikkeling. Throwing-functies moeten expliciet worden gemarkeerd met throws en de compiler vereist try bij aanroep — dit elimineert onafgehandelde fouten tijdens compilatie.
Ja, async-functies kunnen ook throws zijn, en do-catch werkt voor hen. Het aanroepen van een async throwing-functie vereist try await binnen een do-blok. Dit is de standaard manier van foutafhandeling in asynchrone Swift-code.
Er zijn alternatieven: try? converteert de fout naar nil, try! veroorzaakt een crash bij een fout, en rethrows maakt het mogelijk de fout uit een closure door te geven. Do-catch blijft de primaire manier van expliciete afhandeling.
Swift typeert gegooiden fouten niet — elke throwing-functie kan elk type gooien dat voldoet aan Error. Verdeel de afhandeling via matching in catch op specifieke fouttypen.
Ja, dit is de beste praktijk. Definieer AppError als een enum met Error-bevestiging en converteer systeemfouten naar domeinfouten. Dit uniformeert de afhandeling en isoleert de applicatielaag van systeemdetails.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook