Do-Catch: bu nədir, konstruksiya və Swift-də xəta idarəetməsi

Müəllif: IT Sectr Dərc olunub: 2026-05-26 Oxuma vaxtı: 8 dəq

Do-Catch — throw vasitəsilə atılan istisnaları tutan və müvafiq kod blokunu icra edən Swift dilində xəta idarəetmə konstruksiyası. Digər dillərdə ənənəvi try-catch-dən fərqli olaraq, Swift xəta ata bilən funksiyaların throws modifikatoru ilə açıq şəkildə qeyd edilməsini tələb edir. Swift.org, 2026-ya görə, Do-Catch Swift-də tip səviyyəsində təhlükəsizliyi təmin edən əsas xəta idarəetmə mexanizmidir.

Əsas məqamlar

  • Do-Catch — try və throw ilə bloklardan xətaları tutan Swift konstruksiyası.
  • throws — funksiyanın xəta ata biləcəyini bildirən marker.
  • try — do-bloku daxilində throwing-funksiyasını çağırmaq üçün açar söz.
  • catch — tipə görə uyğunlaşdırma imkanı ilə xəta idarəetmə bloku.
  • try?try! — xətanı nil-ə çevirən və ya crash-ə səbəb olan alternativ formalar.

Do-Catch nədir?

Do-Catch — bu, Swift-də do blokundan ibarət konstruksiyadır, onun daxilində xəta ata bilən kod icra olunur və bir və ya bir neçə catch bloku bu xətanı idarə edir. Do bloku try ilə qeyd olunmuş throwing-funksiyalarının çağırışlarını ehtiva edir, catch blokları isə xətanı tipinə görə uyğunlaşdırır.

Swift Objective-C-dəki istisnalardan fərqlənən strukturlaşdırılmış xəta idarəetmə modelini tətbiq edir. Burada xəta stack-in açılması ilə exception deyil, Error protokoluna uyğun gələn dəyərdir. Throw vasitəsilə xətanın atılması idarəetməni stack-in açılması xərci olmadan ən yaxın catch blokuna ötürür.

Swift-in əsas xüsusiyyəti — idarəetmənin aşkarlığı. Kompilyator throwing-funksiyasını try, do-catch və ya alternativ mexanizm (try?, try!) olmadan çağırmağa icazə vermir. Bu, xətanın diqqətdən kənarda qaldığı halları istisna edir.

Swift-də xəta modeli: Error protokolu və throwing funksiyaları

Swift-də xəta idarəetməsinin əsasında Error protokolu dayanır. Bu protokola uyğun gələn istənilən tip throw vasitəsilə atıla bilər. Adətən xətalar Error təsdiqi ilə enum kimi təyin edilir.

Error protokolu

Error — boş protokoldur (marker). Metodların icrasını tələb etmir, yalnız uyğunluğun təsdiqini tələb edir. Swift kompilyatoru statik yoxlama üçün Error-dan istifadə edir: throws olan funksiya yalnız Error-a uyğun gələn dəyəri ata bilər.

Throwing funksiyaları

throws ilə qeyd olunmuş funksiya try ilə çağırılmalıdır. Əgər belə bir funksiyanın daxilində throw baş verərsə, idarəetmə çağıran do-catch-ə ötürülür. Xəta çağırış zəncirinin heç bir yerində idarə olunmazsa, o, yuxarı səviyyəyə ötürülür.

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)
}

Xətanın rethrows ilə ötürülməsi

rethrows — parametr kimi throwing-kapanışını qəbul edən funksiyalar üçün modifikator. Ötürülən kapanış xəta atmazsa, rethrows funksiyasını try olmadan çağırmaq olar. Bu, throwing və non-throwing kapanışları ilə uyğun gələn ümumi yüksək səviyyəli funksiyalar yazmağa imkan verir.

Do-Catch sintaksisi: çoxsaylı catch blokları

Swift xəta növünə görə uyğunlaşdırma ilə çoxsaylı catch bloklarını dəstəkləyir. Bu, Kotlin-də when və ya tipə görə switch-ə bənzəyir: ilk uyğun gələn catch icra olunur, qalanları ötürülür.

Tipə görə uyğunlaşdırma

Hər bir catch bloku müəyyən bir xəta növü ilə uyğunlaşdırma nümunəsi ehtiva edə bilər. Swift blokları sıra ilə yoxlayır, buna görə daha spesifik növlər ümumi olanlardan əvvəl yerləşməlidir. Heç bir nümunə uyğun gəlmirsə, nümunəsiz catch bloku icra olunur.

Çoxsaylı növlərin idarə edilməsi

Tip təhlükəsizliyi Do-Catch hər bir xətanı ayrıca idarə etməyə və ya pattern-matching-də vergül vasitəsilə bir blokda bir neçə növü birləşdirməyə imkan verir. Bu, Objective-C üçün xarakterik olan, xəta təhlilinin qaytarma kodu və ya domain və code yoxlaması ilə NSError vasitəsilə aparıldığı həcmli if-else zəncirlərini aradan qaldırır.

Swift həmçinin catch where — əlavə şərtlə uyğunlaşdırmanı dəstəkləyir. Məsələn, xətaları konkret kod və ya mətnə görə filtr etmək olar: catch URLError where error.code == .notConnectedToInternet. Bu, idarəetmənin dəqiqliyini qoruyaraq catch bloklarının sayını azaldır.

Throwing funksiyalarının debug edilməsi üçün Swift xətalar və istisnalar arasındakı fərqi təmin edir. Swift xətası — stack-in açılmasını tələb etməyən qaytarılan dəyərdir. Objective-C istisnaları (@try/@catch) runtime səviyyəsində işləyir və yalnız kritik nasazlıqlar üçün istifadə olunur. Do-Catch məhz xətaları idarə edir, istisnaları yox, bu da onu proqnozlaşdırıla bilən və məhsuldar edir.

Kitabxana və SDK-ların hazırlanmasında yadda saxlamaq lazımdır ki, throwing funksiyaları ictimai müqavilənin bir hissəsidir. Xəta növü imzada göstərilmir, buna görə də funksiyanın hansı xətaları ata biləcəyini şərhdə və ya Result bənzəri enum vasitəsilə sənədləşdirin. Bu, API istifadəçilərinə tətbiqə baxmadan düzgün catch blokları yazmağa kömək edir.

Asinxron proqramlaşdırma kontekstində async/await ilə Do-Catch callback hell problemini həll edir. Əvvəllər Swift-də asinxron koddakı xətaların idarə edilməsi completion handler-də Error? yoxlaması ilə iç-içə kapanışlar tələb edirdi. async/await və Do-Catch ilə asinxron throwing kodu sinxron kimi görünür, bu da hər addımda xəta idarəetməsi ilə mürəkkəb sorğu zəncirlərinin oxunmasını və saxlanmasını asanlaşdırır.

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("Naməlum xəta: \(error)")
}

Try variantları: try, try?, try! və nə vaxt istifadə edilməli

Swift throwing funksiyalarını çağırmaq üçün üç variant təklif edir: try, try?try!. Hər variant konkret bir vəzifəni həll edir və öz məhdudiyyətlərinə malikdir.

try — standart çağırış

try do bloku daxilində istifadə olunur və xəta catch-də idarə olunur. Bu, throwing funksiyalarını çağırmağın əsas yoludur. Kompilyator try-nin xətanın tutula biləcəyi kontekstdə olmasını tələb edir.

try? — Optional-a çevirmə

try? throwing funksiyasının nəticəsini Optional-a çevirir. Funksiya xəta atarsa, try? nil qaytarır, əks halda — uğurlu dəyərlə Optional. Xətanı göz ardı etmək mümkün olduğu, lakin uğur göstəricisinə ehtiyac duyulan çağırışlar üçün əlverişlidir.

try! — məcburi icra

try! xəta idarəetməsini boğur. Throwing funksiyası xəta atarsa, tətbiq runtime xətası ilə dayanır. try!-dən yalnız xətanın qətiyyən mümkün olmadığına tam əmin olduqda istifadə edin — məsələn, daxili resursu yükləyərkən.

swift
// try? — xətanı göz ardı edirik, nasazlıqda nil alırıq
if let data = try? Data(contentsOf: url) {
    processData(data)
}

// try! — yalnız xəta qətiyyən mümkün deyilsə
let bundled = try! String(contentsOfFile: "Assets/default.txt")

// try — do-catch-də standart variant
do {
    let result = try performNetworkRequest()
    updateUI(result)
} catch {
    showError(error)
}

iOS inkişafında Do-Catch: praktiki nümunələr

Do-Catch iOS inkişafında sistem API-ləri ilə işləmək üçün fəal şəkildə istifadə olunur. Tipik ssenariləri nəzərdən keçirək: fayl sistemi ilə iş, Core Data və şəbəkə sorğuları.

Fayl sistemi

FileManager-in bir çox metodu throwing-dir. Do-Catch faylın olmaması, resursun məşğul olması və ya icazələrin çatışmazlığını düzgün idarə etməyə imkan verir.

Codable ilə şəbəkə sorğuları

JSONDecoder vasitəsilə JSON-un pars edilməsi — throwing əməliyyatıdır. Do-Catch deşifrləmə xətalarını və şəbəkə nasazlıqlarını ayrıca tutaraq istifadəçiyə dəqiq xəta mətnini təqdim edir.

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)
}

// İdarəetmə ilə çağırış
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)
}

Do-Catch ilə işləyərkən tipik səhvlər

Tərtibatçılar, xüsusilə digər dillərdən keçənlər, Do-Catch-dən istifadə edərkən xarakterik səhvlərə yol verirlər. Ən geniş yayılmışları nəzərdən keçirək.

  • Unudulmuş try — try olmadan throwing funksiyasını çağırmaq kompilyasiya xətasına səbəb olur. Swift xətaları örtülü şəkildə göz ardı etməyə icazə vermir.
  • Boş catch — idarəetmə olmadan catch bloku xətanı gizlədir. Həmişə xətanı log edin və ya idarə edin, hətta qeyri-mümkün görünsə belə.
  • Uyğunlaşdırmasız catch — bütün xətalar üçün bir ümumi catch tip təhlükəsizliyinin üstünlüklərini itirir. İdarəetməni bir neçə blok vasitəsilə növlərə görə bölün.
  • try!-nin həddindən artıq istifadəsi — production kodunda try! gözlənilməz crash mənbəyidir. Yalnız daxili resurslar və ya testlər üçün istifadə edin.

Tez-tez verilən suallar

Swift-də Do-Catch digər dillərdəki try-catch-dən nə ilə fərqlənir?

Swift-də xəta stack-in açılması ilə exception deyil, Error protokoluna uyğun gələn dəyərdir. Throwing funksiyaları açıq şəkildə throws ilə qeyd edilməlidir və kompilyator çağırış zamanı try tələb edir — bu, kompilyasiya mərhələsində idarə olunmamış xətaları istisna edir.

Do-Catch async/await ilə istifadə edilə bilərmi?

Bəli, async funksiyaları da throws ola bilər və onlar üçün do-catch işləyir. Async throwing funksiyasını çağırmaq do bloku daxilində try await tələb edir. Bu, Swift-in asinxron kodunda xətaların idarə edilməsinin standart üsuludur.

Do-catch olmadan xətanı necə idarə etmək olar?

Alternativlər var: try? xətanı nil-ə çevirir, try! xəta zamanı crash-ə səbəb olur, rethrows isə xətanı kapanışdan ötürməyə imkan verir. Do-catch açıq idarəetmənin əsas yolu olaraq qalır.

Bir funksiya müxtəlif tip xətalar ata bilərmi?

Swift atılan xətaları tipləşdirmir — istənilən throwing funksiyası Error-a uyğun gələn istənilən tipi ata bilər. İdarəetməni catch-də konkret xəta növlərinə uyğunlaşdırma vasitəsilə bölün.

Bütün xətaları öz xüsusi tipimə bükməyə dəyərmi?

Bəli, bu ən yaxşı təcrübədir. Error təsdiqi ilə enum kimi AppError təyin edin və sistem xətalarını domen xətalarına çevirin. Bu, idarəetməni birləşdirir və tətbiq qatını sistem detallarından təcrid edir.

Nəticə

  • Do-Catch — funksiyalarda throws məcburi qeydi və çağırışda try ilə Swift-də xəta idarəetmə konstruksiyası.
  • Swift xətaları — stack-in açılması ilə istisnalar deyil, Error protokoluna uyğun gələn dəyərlər, bu da nasazlıq olmadıqda sıfır xərc verir.
  • Çoxsaylı catch switch-ə bənzər pattern-matching ilə müxtəlif tip xətaları ayrıca idarə etməyə imkan verir.
  • try? sadə ssenarilər üçün xətanı nil-ə çevirir, try! — yalnız zəmanətli uğurlu əməliyyatlar üçün istifadə olunan crash riski ilə məcburi çağırış.
  • Do-Catch async/await ilə — try await istifadə edərək asinxron Swift kodunda xətaların idarə edilməsinin standart üsulu.
  • Boş catch və try!-nin həddindən artıq istifadəsindən çəkinin — bu, xətaları gizlədir və production-da gözlənilməz nasazlıqlara səbəb olur.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun