Do-Catch — Swift-språkets konstruktion för felhantering som fångar undantag som kastas via throw och utför motsvarande kodblock. Till skillnad från traditionell try-catch i andra språk kräver Swift explicit markering av funktioner som kan kasta ett fel med modifieraren throws. Enligt Swift.org, 2026 är Do-Catch den primära mekanismen för felhantering i Swift, som säkerställer säkerhet på typnivå.
Huvudpunkter
Do-Catch — är en konstruktion i Swift som består av ett do-block, inom vilket kod som kan kasta ett fel körs, och ett eller flera catch-block som hanterar detta fel. Do-blocket innehåller anrop till throwing-funktioner markerade med try, och catch-blocken matchar felet efter typ.
Swift implementerar modellen strukturerad felhantering, som skiljer sig från undantag i Objective-C. Här är ett fel inte ett exception med stackavveckling, utan ett värde som motsvarar protokollet Error. Att kasta ett fel via throw överför kontrollen till närmaste catch-block utan kostnad för stackavveckling.
En nyckelfunktion i Swift — explicit hantering. Kompilatorn tillåter inte anrop av en throwing-funktion utan try, do-catch eller alternativ mekanism (try?, try!). Detta eliminerar situationer där ett fel förblir oupptäckt.
Grunden för felhantering i Swift är protokollet Error. Alla typer som motsvarar detta protokoll kan kastas via throw. Vanligtvis definieras fel som en enum med Error-bekräftelse.
Error — ett tomt protokoll (markör). Det kräver inte implementering av metoder, endast bekräftelse av överensstämmelse. Swift-kompilatorn använder Error för statisk kontroll: en funktion med throws kan bara kasta ett värde som motsvarar Error.
En funktion markerad med throws måste anropas med try. Om en throw inträffar inuti en sådan funktion överförs kontrollen till den anropande do-catch. Om felet inte hanteras någonstans i anropskedjan propageras det till en högre nivå.
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 — en modifierare för funktioner som tar en throwing-closure som parameter. Om den skickade closure inte kastar ett fel kan rethrows-funktionen anropas utan try. Detta gör det möjligt att skriva generiska högre ordningens funktioner som är kompatibla med throwing och non-throwing closures.
Swift stöder flera catch-block med matchning efter feltyp. Detta liknar when i Kotlin eller switch efter typ: den första matchande catch körs, resten hoppas över.
Varje catch-block kan innehålla ett matchmönster för en specifik feltyp. Swift kontrollerar blocken i ordning, så mer specifika typer bör placeras före allmänna. Om inget mönster matchar körs catch-blocket utan mönster.
Typsäkerhet Do-Catch gör det möjligt att hantera varje fel separat eller kombinera flera typer i ett block via kommatecken i pattern-matching. Detta eliminerar omfattande if-else-kedjor som är karakteristiska för Objective-C, där felanalys gjordes via returkod eller NSError med kontroll av domain och code.
Swift stöder också catch where — matchning med ett extra villkor. Man kan till exempel filtrera fel efter specifik kod eller text: catch URLError where error.code == .notConnectedToInternet. Detta minskar antalet catch-block samtidigt som precisionen i hanteringen bibehålls.
För felsökning av throwing-funktioner tillhandahåller Swift skillnaden mellan fel och undantag. Ett Swift-fel är ett returnerat värde som inte kräver stackavveckling. Objective-C-undantag (@try/@catch) fungerar på runtime-nivå och används endast för allvarliga fel. Do-Catch hanterar just fel, inte undantag, vilket gör det förutsägbart och prestandaeffektivt.
Vid utveckling av bibliotek och SDK är det viktigt att komma ihåg att throwing-funktioner är en del av det offentliga kontraktet. Feltypen specificeras inte i signaturen, så dokumentera vilka fel funktionen kan kasta i en kommentar eller via en Result-liknande enum. Detta hjälper API-användare att skriva korrekta catch-block utan att behöva titta på implementeringen.
I sammanhanget av asynkron programmering löser Do-Catch med async/await callback hell-problemet. Tidigare i Swift krävde felhantering i asynkron kod kapslade closures med Error?-kontroll i completion handler. Med async/await och Do-Catch ser asynkron throwing-kod ut som synkron kod, vilket förenklar läsning och underhåll av komplexa kedjor med felhantering vid varje steg.
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("Okänt fel: \(error)")
}
Swift erbjuder tre varianter för att anropa throwing-funktioner: try, try? och try!. Varje variant löser en specifik uppgift och har sina begränsningar.
try används inuti ett do-block och felet hanteras i catch. Detta är det primära sättet att anropa throwing-funktioner. Kompilatorn kräver att try befinner sig i en kontext där felet kan fångas.
try? konverterar resultatet av en throwing-funktion till Optional. Om funktionen kastar ett fel returnerar try? nil, annars — Optional med ett lyckat värde. Användbart för anrop där felet kan ignoreras men en indikator på framgång behövs.
try! undertrycker felhantering. Om throwing-funktionen kastar ett fel avslutas applikationen med ett runtime-fel. Använd try! endast när du är absolut säker på att felet är omöjligt — till exempel vid inläsning av en inbäddad resurs.
// try? — ignorerar felet, får nil vid fel
if let data = try? Data(contentsOf: url) {
processData(data)
}
// try! — endast om felet är garanterat omöjligt
let bundled = try! String(contentsOfFile: "Assets/default.txt")
// try — standardalternativ i do-catch
do {
let result = try performNetworkRequest()
updateUI(result)
} catch {
showError(error)
}
Do-Catch används aktivt i iOS-utveckling för arbete med system-API:er. Låt oss titta på typiska scenarier: arbete med filsystemet, Core Data och nätverksförfrågningar.
Många metoder i FileManager är throwing. Do-Catch gör det möjligt att korrekt hantera saknade filer, upptagna resurser eller otillräckliga behörigheter.
JSON-tolkning via JSONDecoder — en throwing-operation. Do-Catch fångar avkodningsfel och nätverksfel separat och ger användaren exakt feltext.
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)
}
// Anrop med hantering
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)
}
Utvecklare, särskilt de som kommer från andra språk, gör ofta karakteristiska misstag när de använder Do-Catch. Låt oss titta på de vanligaste.
Vanliga frågor
I Swift är ett fel ett värde som motsvarar Error-protokollet, inte ett exception med stackavveckling. Throwing-funktioner måste explicit markeras med throws och kompilatorn kräver try vid anrop — detta eliminerar ohanterade fel i kompileringsfasen.
Ja, async-funktioner kan också vara throws och do-catch fungerar för dem. Anrop av en async throwing-funktion kräver try await inuti ett do-block. Detta är standardsättet för felhantering i asynkron Swift-kod.
Det finns alternativ: try? omvandlar felet till nil, try! orsakar en crash vid fel och rethrows gör det möjligt att propagerar felet från en closure. Do-catch förblir det primära sättet för explicit hantering.
Swift typifierar inte kastade fel — vilken throwing-funktion som helst kan kasta vilken typ som helst som motsvarar Error. Separera hanteringen genom matchning i catch mot specifika feltyper.
Ja, detta är bästa praxis. Definiera AppError som en enum med Error-bekräftelse och konvertera systemfel till domänfel. Detta förenar hanteringen och isolerar applikationslagret från systemdetaljer.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också