Do-Catch — construcția limbajului Swift pentru gestionarea erorilor, care interceptează excepțiile aruncate prin throw și execută blocul de cod corespunzător. Spre deosebire de try-catch tradițional din alte limbaje, Swift necesită marcarea explicită a funcțiilor care pot arunca o eroare cu modificatorul throws. Potrivit Swift.org, 2026, Do-Catch este mecanismul principal de gestionare a erorilor în Swift, asigurând siguranța la nivel de tipuri.
Principalele
Do-Catch — este o construcție în Swift formată dintr-un bloc do, în interiorul căruia se execută codul capabil să arunce o eroare, și unul sau mai multe blocuri catch care gestionează această eroare. Blocul do conține apeluri ale funcțiilor throwing marcate cu try, iar blocurile catch potrivesc eroarea după tip.
Swift implementează modelul de gestionare structurată a erorilor, diferit de excepțiile din Objective-C. Aici eroarea nu este o excepție cu derularea stivei, ci o valoare care corespunde protocolului Error. Aruncarea erorii prin throw transferă controlul către cel mai apropiat bloc catch fără costurile derulării stivei.
Caracteristica cheie a Swift — explicitatea gestionării. Compilatorul nu permite apelarea unei funcții throwing fără try, do-catch sau un mecanism alternativ (try?, try!). Aceasta elimină situațiile în care o eroare rămâne neobservată.
La baza gestionării erorilor în Swift stă protocolul Error. Orice tip care corespunde acestui protocol poate fi aruncat prin throw. De obicei, erorile sunt definite ca enum cu confirmarea Error.
Error — un protocol gol (marcator). Nu necesită implementarea metodelor, doar confirmarea conformității. Compilatorul Swift folosește Error pentru verificarea statică: o funcție cu throws poate arunca doar o valoare care corespunde lui Error.
O funcție marcată cu throws trebuie apelată cu try. Dacă în interiorul unei astfel de funcții are loc throw, controlul este transferat în do-catch-ul apelant. Dacă eroarea nu este gestionată nicăieri în lanțul de apeluri, este propagată la nivelul superior.
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 — un modificator pentru funcțiile care acceptă un throwing-closure ca parametru. Dacă closure-ul transmis nu aruncă o eroare, funcția rethrows poate fi apelată fără try. Acest lucru permite scrierea funcțiilor generice de ordin superior compatibile cu closure-uri throwing și non-throwing.
Swift suportă multiple blocuri catch cu potrivire după tipul erorii. Aceasta seamănă cu when în Kotlin sau switch după tip: primul catch potrivit se execută, restul sunt sărite.
Fiecare bloc catch poate conține un model de potrivire cu un tip specific de eroare. Swift verifică blocurile în ordine, deci tipurile mai specifice trebuie să se afle înaintea celor generale. Dacă niciun model nu se potrivește, se execută blocul catch fără model.
Siguranța tipurilor Do-Catch permite gestionarea fiecărei erori separat sau combinarea mai multor tipuri într-un singur bloc prin virgulă în pattern-matching. Aceasta elimină lanțurile voluminoase if-else caracteristice Objective-C, unde analiza erorii se făcea prin codul de returnare sau NSError cu verificarea domain și code.
Swift suportă de asemenea catch where — potrivirea cu o condiție suplimentară. De exemplu, se pot filtra erorile după un cod sau text specific: catch URLError where error.code == .notConnectedToInternet. Aceasta reduce numărul blocurilor catch păstrând precizia gestionării.
Pentru depanarea funcțiilor throwing, Swift oferă diferența dintre erori și excepții. Eroarea Swift — este o valoare returnată care nu necesită derularea stivei. Excepțiile Objective-C (@try/@catch) funcționează la nivel de runtime și sunt folosite doar pentru defecțiuni fatale. Do-Catch gestionează exact erorile, nu excepțiile, ceea ce îl face previzibil și performant.
La dezvoltarea bibliotecilor și SDK-urilor, este important de reținut că funcțiile throwing fac parte din contractul public. Tipul erorii nu este specificat în semnătură, prin urmare documentați ce erori poate arunca funcția într-un comentariu sau printr-un enum de tip Result. Acest lucru ajută utilizatorii API să scrie blocuri catch corecte fără a se uita în implementare.
În contextul programării asincrone, Do-Catch cu async/await rezolvă problema callback hell. Anterior, în Swift, gestionarea erorilor în codul asincron necesita closure-uri imbricate cu verificarea Error? în completion handler. Cu async/await și Do-Catch, codul asincron throwing arată ca cel sincron, simplificând citirea și întreținerea lanțurilor complexe de cereri cu gestionarea erorilor la fiecare pas.
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("Eroare necunoscută: \(error)")
}
Swift oferă trei variante de apelare a funcțiilor throwing: try, try? și try!. Fiecare variantă rezolvă o sarcină specifică și are limitările sale.
try este folosit în interiorul blocului do, iar eroarea este gestionată în catch. Aceasta este modalitatea principală de apelare a funcțiilor throwing. Compilatorul cere ca try să se afle într-un context în care eroarea poate fi interceptată.
try? convertește rezultatul funcției throwing în Optional. Dacă funcția aruncă o eroare, try? returnează nil, altfel — Optional cu valoarea de succes. Util pentru apeluri unde eroarea poate fi ignorată, dar este necesar un indicator de succes.
try! suprima gestionarea erorilor. Dacă funcția throwing aruncă o eroare, aplicația se termină cu eroare de runtime. Folosiți try! doar când sunteți absolut sigur că eroarea este imposibilă — de exemplu, la încărcarea unei resurse încorporate.
// try? — ignorăm eroarea, primim nil la defecțiune
if let data = try? Data(contentsOf: url) {
processData(data)
}
// try! — doar dacă eroarea este garantat imposibilă
let bundled = try! String(contentsOfFile: "Assets/default.txt")
// try — varianta standard în do-catch
do {
let result = try performNetworkRequest()
updateUI(result)
} catch {
showError(error)
}
Do-Catch este folosit activ în dezvoltarea iOS pentru lucrul cu API-urile sistemului. Să analizăm scenariile tipice: lucrul cu sistemul de fișiere, Core Data și cererile de rețea.
Multe metode ale FileManager sunt throwing. Do-Catch permite gestionarea corectă a absenței fișierului, ocupării resursei sau lipsei de permisiuni.
Parsarea JSON prin JSONDecoder — o operație throwing. Do-Catch interceptează erorile de decodare și defecțiunile de rețea separat, oferind utilizatorului textul exact al erorii.
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)
}
// Apel cu gestionare
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)
}
Dezvoltatorii, în special cei care trec de la alte limbaje, fac adesea greșeli caracteristice când folosesc Do-Catch. Să analizăm cele mai frecvente.
Întrebări frecvente
În Swift eroarea este o valoare care corespunde protocolului Error, nu o excepție cu derularea stivei. Funcțiile throwing trebuie să fie marcate explicit cu throws, iar compilatorul cere try la apel — aceasta elimină erorile negestionate în faza de compilare.
Da, funcțiile async pot fi de asemenea throws, iar do-catch funcționează pentru ele. Apelul unei funcții async throwing necesită try await în interiorul blocului do. Aceasta este modalitatea standard de gestionare a erorilor în codul asincron Swift.
Există alternative: try? transformă eroarea în nil, try! provoacă un crash la eroare, iar rethrows permite propagarea erorii din closure. Do-catch rămâne modalitatea principală de gestionare explicită.
Swift nu tipizează erorile aruncate — orice funcție throwing poate arunca orice tip care corespunde lui Error. Separați gestionarea prin potrivire în catch după tipuri specifice de erori.
Da, aceasta este cea mai bună practică. Definiți AppError ca enum cu confirmarea Error și convertiți erorile sistemice în erori de domeniu. Aceasta unifică gestionarea și izolează stratul aplicației de detaliile sistemice.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și