Saya belum banyak membaca Swift tetapi satu hal yang saya perhatikan adalah tidak ada pengecualian. Jadi bagaimana mereka melakukan penanganan kesalahan di Swift? Adakah yang menemukan sesuatu yang berhubungan dengan penanganan kesalahan?
swift
error-handling
peko
sumber
sumber
Jawaban:
Swift 2 & 3
Banyak hal telah berubah sedikit di Swift 2, karena ada mekanisme penanganan kesalahan baru, yang agak lebih mirip dengan pengecualian tetapi berbeda dalam detailnya.
1. Menunjukkan kemungkinan kesalahan
Jika fungsi / metode ingin menunjukkan bahwa ia dapat menimbulkan kesalahan, itu harus mengandung
throws
kata kunci seperti iniCatatan: tidak ada spesifikasi untuk jenis kesalahan yang dapat dilemparkan oleh fungsi tersebut. Deklarasi ini hanya menyatakan bahwa fungsi tersebut dapat melempar instance dari jenis apa pun yang menerapkan ErrorType atau tidak melempar sama sekali.
2. Memohon fungsi yang dapat menyebabkan kesalahan
Untuk menjalankan fungsi, Anda perlu menggunakan kata kunci coba, seperti ini
baris ini biasanya harus ada blok do-catch seperti ini
Catatan: catch clause menggunakan semua fitur canggih pencocokan pola Swift sehingga Anda sangat fleksibel di sini.
Anda dapat memutuskan untuk menyebarkan kesalahan, jika Anda memanggil fungsi melempar dari fungsi yang ditandai dengan
throws
kata kunci:Atau, Anda dapat memanggil fungsi melempar menggunakan
try?
:Dengan cara ini Anda mendapatkan nilai kembali atau nihil, jika terjadi kesalahan. Dengan menggunakan cara ini Anda tidak mendapatkan objek kesalahan.
Yang berarti Anda juga dapat menggabungkan
try?
dengan pernyataan berguna seperti:atau
Akhirnya, Anda dapat memutuskan bahwa Anda tahu bahwa kesalahan tidak akan benar-benar terjadi (misalnya karena Anda telah memeriksa prasyarat) dan menggunakan
try!
kata kunci:Jika fungsi tersebut benar-benar melempar kesalahan, maka Anda akan mendapatkan kesalahan runtime di aplikasi Anda dan aplikasi akan berakhir.
3. Melempar kesalahan
Untuk melempar kesalahan, Anda menggunakan kata kunci melempar seperti ini
Anda dapat membuang apa pun yang sesuai dengan
ErrorType
protokol. Sebagai permulaanNSError
sesuai dengan protokol ini, tetapi Anda mungkin ingin menggunakan berbasis enumErrorType
yang memungkinkan Anda untuk mengelompokkan beberapa kesalahan terkait, berpotensi dengan potongan data tambahan, seperti iniPerbedaan utama antara mekanisme kesalahan Swift 2 & 3 baru dan pengecualian gaya Java / C # / C ++ adalah sebagai berikut:
do-catch
+try
+defer
vstry-catch-finally
sintaksis tradisional .do-catch
Blok Anda tidak akan menangkap NSException, dan sebaliknya, untuk itu Anda harus menggunakan ObjC.NSError
konvensi metode Kakao untuk mengembalikanfalse
(untukBool
fungsi kembali) ataunil
(untukAnyObject
fungsi kembali) dan meneruskanNSErrorPointer
dengan detail kesalahan.Sebagai tambahan sintaksis-gula untuk memudahkan penanganan kesalahan, ada dua konsep lagi
defer
kata kunci) yang memungkinkan Anda mencapai efek yang sama dengan akhirnya memblokir di Java / C # / etcguard
kata kunci) yang memungkinkan Anda menulis kode if / else lebih sedikit dari pada kode pengecekan / pensinyalan kesalahan normal.Cepat 1
Kesalahan runtime:
Seperti yang disarankan Leandros untuk menangani kesalahan runtime (seperti masalah konektivitas jaringan, parsing data, file pembukaan, dll) Anda harus menggunakan
NSError
seperti yang Anda lakukan di ObjC, karena Foundation, AppKit, UIKit, dll melaporkan kesalahan mereka dengan cara ini. Jadi lebih banyak hal kerangka daripada hal bahasa.Pola lain yang sering digunakan adalah blok sukses / gagal pemisah seperti di AFNetworking:
Masih blok kegagalan sering diterima
NSError
contoh, menggambarkan kesalahan.Kesalahan pemrogram:
Untuk kesalahan programmer (seperti akses di luar batas elemen array, argumen tidak valid diteruskan ke panggilan fungsi, dll) Anda menggunakan pengecualian di ObjC. Bahasa Swift tampaknya tidak memiliki dukungan bahasa untuk pengecualian (seperti
throw
,catch
, dll kata kunci). Namun, seperti yang ditunjukkan oleh dokumentasi, ia menjalankan runtime yang sama dengan ObjC, dan karenanya Anda masih dapat melemparNSExceptions
seperti ini:Anda tidak dapat menangkapnya dalam Swift murni, meskipun Anda dapat memilih untuk menangkap pengecualian dalam kode ObjC.
Pertanyaannya adalah apakah Anda harus melempar pengecualian untuk kesalahan programmer, atau lebih tepatnya menggunakan pernyataan seperti yang disarankan Apple dalam panduan bahasa.
sumber
fatalError(...)
sama juga.Perbarui 9 Juni 2015 - Sangat penting
Swift 2.0 hadir dengan
try
,,throw
dancatch
kata kunci dan yang paling menarik adalah:Kutipan dari: Apple Inc. “Menggunakan Swift dengan Kakao dan Objective-C (Swift 2 Prerelease).” iBooks.
Contoh: (dari buku)
Setara dengan swift adalah:
Melempar Kesalahan:
Akan secara otomatis disebarkan ke penelepon:
Dari buku-buku Apple, The Swift Programming Language, tampaknya kesalahan harus ditangani menggunakan enum.
Ini adalah contoh dari buku ini.
Dari: Apple Inc. "Bahasa Pemrograman Swift." iBooks. https://itun.es/br/jEUH0.l
Memperbarui
Dari buku-buku berita Apple, "Menggunakan Swift dengan Kakao dan Objective-C". Pengecualian runtime tidak terjadi menggunakan bahasa cepat, jadi itu sebabnya Anda tidak memiliki try-catch. Sebagai gantinya Anda menggunakan Chaining Opsional .
Ini adalah peregangan dari buku ini:
Kutipan dari: Apple Inc. “Menggunakan Swift dengan Kakao dan Objective-C.” iBooks. https://itun.es/br/1u3-0.l
Dan buku-buku itu juga mendorong Anda untuk menggunakan pola kesalahan kakao dari Objective-C (NSError Object)
Kutipan dari: Apple Inc. “Menggunakan Swift dengan Kakao dan Objective-C.” iBooks. https://itun.es/br/1u3-0.l
sumber
Tidak ada Pengecualian di Swift, mirip dengan pendekatan Objective-C.
Dalam pengembangan, Anda dapat menggunakan
assert
untuk menangkap kesalahan yang mungkin muncul, dan perlu diperbaiki sebelum mulai berproduksi.NSError
Pendekatan klasik tidak diubah, Anda mengirimNSErrorPointer
, yang akan diisi.Contoh singkat:
sumber
f();g();
menjadif(&err);if(err) return;g(&err);if(err) return;
untuk bulan pertama, maka itu hanya menjadif(nil);g(nil);hopeToGetHereAlive();
'Swift Way' yang disarankan adalah:
Namun saya lebih suka mencoba / menangkap karena saya merasa lebih mudah untuk mengikuti karena memindahkan penanganan kesalahan ke blok yang terpisah di akhir, pengaturan ini kadang-kadang disebut "Jalur Emas". Beruntung Anda bisa melakukan ini dengan penutupan:
Juga mudah untuk menambahkan fasilitas coba lagi:
Daftar untuk TryBool adalah:
Anda dapat menulis kelas serupa untuk menguji nilai yang dikembalikan opsional dan bukan nilai Bool:
Versi TryOptional memberlakukan jenis pengembalian non-opsional yang membuat pemrograman berikutnya lebih mudah, misalnya 'Swift Way:
Menggunakan TryOptional:
Catatan buka otomatis.
sumber
Edit: Walaupun jawaban ini berhasil, ini lebih dari Objective-C yang ditransliterasikan ke dalam Swift. Itu telah dibuat usang oleh perubahan dalam Swift 2.0. Jawaban Guilherme Torres Castro di atas adalah pengantar yang sangat bagus untuk cara penanganan kesalahan yang disukai di Swift. VOS
Butuh sedikit mencari tahu tapi saya pikir saya sudah sussed itu. Sepertinya jelek. Tidak lebih dari kulit tipis di atas versi Objective-C.
Memanggil fungsi dengan parameter NSError ...
Menulis fungsi yang mengambil parameter kesalahan ...
sumber
Pembungkus dasar di sekitar tujuan C yang memberi Anda fitur coba tangkap. https://github.com/williamFalcon/SwiftTryCatch
Gunakan seperti:
sumber
Ini adalah jawaban pembaruan untuk swift 2.0. Saya menantikan fitur penanganan model yang kaya fitur seperti di java. Akhirnya, mereka mengumumkan kabar baik. sini
misalnya:
sumber
Sebagai Guilherme Torres Castro mengatakan, di Swift 2.0,
try
,catch
,do
dapat digunakan dalam pemrograman.Sebagai contoh, Di CoreData mengambil metode data, bukannya dimasukkan
&error
sebagai parameter ke dalammanagedContext.executeFetchRequest(fetchRequest, error: &error)
, sekarang kita hanya perlu menggunakan gunakanmanagedContext.executeFetchRequest(fetchRequest)
dan kemudian menangani kesalahan dengantry
,catch
( Apple Document Link )Jika Anda sudah mengunduh xcode7 Beta. Cobalah untuk mencari kesalahan melempar dalam Dokumentasi dan Referensi API dan pilih hasil pertama yang ditampilkan, itu memberikan ide dasar apa yang dapat dilakukan untuk sintaks baru ini. Namun, dokumentasi lengkap belum dikirim untuk banyak API.
Teknik penanganan kesalahan yang lebih mewah dapat ditemukan di
sumber
Penanganan kesalahan adalah fitur baru dari Swift 2.0. Ini menggunakan
try
,throw
dancatch
kata kunci.Lihat pengumuman Apple Swift 2.0 di blog resmi Apple Swift
sumber
Lib bagus dan sederhana untuk menangani pengecualian: TryCatchFinally-Swift
Seperti beberapa yang lain, ia membungkus fitur pengecualian C objektif.
Gunakan seperti ini:
sumber
Dimulai dengan Swift 2, seperti yang telah disebutkan orang lain, penanganan kesalahan paling baik dilakukan melalui penggunaan do / try / catch dan enum ErrorType. Ini bekerja cukup baik untuk metode sinkron, tetapi sedikit kepintaran diperlukan untuk penanganan kesalahan yang tidak sinkron.
Artikel ini memiliki pendekatan yang bagus untuk masalah ini:
https://jeremywsherman.com/blog/2015/06/17/using-swift-throws-with-completion-callbacks/
Untuk meringkas:
kemudian, panggilan ke metode di atas adalah sebagai berikut:
Ini tampaknya sedikit lebih bersih daripada memiliki error yang terpisah Callback handler dilewatkan ke fungsi asinkron, yang bagaimana ini akan ditangani sebelum Swift 2.
sumber
Apa yang saya lihat adalah bahwa karena sifat perangkat Anda tidak ingin melempar sekelompok pesan penanganan kesalahan cryptic pada pengguna. Itu sebabnya sebagian besar fungsi mengembalikan nilai opsional maka Anda hanya kode untuk mengabaikan opsional. Jika suatu fungsi kembali nihil artinya gagal Anda dapat pop pesan atau apa pun.
sumber