在本章中,你将學會
ErrorHandling
異常處理的使用方法。
前言
和
Apple
官網或者網上分享的教程類文章不同,我将以實際開發角度講述
Swift
語言的一些概念和用法,友善大家更好地學習和掌握
Swift
語言。
這同時也是對自己學習
Swift
語言過程的知識整理。
如有錯誤,以你為準。
錯誤處理的定義
錯誤處理(
Error handling
),是響應錯誤以及從錯誤中恢複的過程。
在
Swift
開發過程中,我們常常會遇到由于一些方法無法執行或者參數丢失等原因導緻的系統報錯問題,嚴重一點可能會導緻系統奔潰。而錯誤處理(
Error handling
),正是當這樣那樣的問題發生時,系統能夠檢測到錯誤并告知我們。
錯誤情況的建立
我們建立一個
PlayGround
項目,命名為
SwiftErrorHandling
。
要想使用
Swift
錯誤處理的方法,首先我們需要知道有可能存在哪些會引發錯誤的問題。
對于這些問題,我們通常可以使用枚舉的方式建構錯誤結果的項。示例:
enum AllError: Error {
case error1
case error2
case
上述代碼中,我們建立了一個
AllError
的枚舉,它遵循
Error
協定。
Error
協定是
Swift
文法中,我們抛出錯誤時,錯誤情況的枚舉類型需要遵守自
Error
協定。
對于
AllError
的枚舉,我們聲明了3中錯誤情況:
error1
、
error2
、
error3
。
當然,這可以自己按照業務情況設定相應的錯誤項,比如在字典中,可以使用
case emptyKey
表示字典中
key
的值為空這種錯誤情況。
如果我們需要錯誤情況的結果添加描述資訊,用通俗的描述文字告知使用者這個錯誤是什麼意思,則需要遵循
LocalizedError
協定,我們寫一個
extension
拓展來描述資訊。示例:
extension AllError: LocalizedError {
var errorDescription: String? {
switch self {
case .error1:
return "第一個錯誤"
case .error2:
return "第二個錯誤"
case .error3:
return "第三個錯誤"
上述代碼中,我們拓展了
AllError
枚舉,它遵循
LocalizedError
協定。
然後我們聲明了一個可選
String
類型的
errorDescription
變量來作為描述資訊,我們根據枚舉的不同結果傳回輸出不同的錯誤資訊文字。
如果是需要不基于枚舉的項自定義錯誤結果,那麼我們需要讓拓展遵循
CustomNSError
協定。示例:
extension AllError: CustomNSError{
var errorCode: Int{
return 404
上述代碼中,我們拓展了
AllError
枚舉,它遵循
CustomNSError
協定。
然後我們聲明了一個
Int
類型的變量
errorCode
,當我們錯誤發生時,傳回
404
。
錯誤情況的抛出
上面,我們已經定義好了錯誤情況的結果,那麼在實際業務當中,我們可以對可能存在錯誤的場景進行判斷,并抛出錯誤資訊。示例:
func LoginError(username: String?) throws {
if username == nil {
throw AllError.error1
} else {
print("username不為空")
}
}
上述代碼中,我們定義了一個
LoginError
的方法,它接收可選
String
類型的
username
的值,如果這個值為
nil
,那麼我們就使用
throw
關鍵字将
Error
類型的錯誤抛出。
我們使用
throw
關鍵字時,方法聲明中就必須使用
throws
來接收錯誤。
錯誤情況的處理
上面,我們建立了錯誤情況的結果和描述,然後也在具體業務中可以抛出即接收錯誤情況資訊,下面,我們對異常情況進行處理。
Swift
提供了三種集中處理錯誤的方法:
try、try?、try!
。定義如下:
try:Error将自動抛給上層函數。如果最終沒人處理到main函數,系統一樣會崩潰閃退。
try?: Error将傳回nil,不向上傳遞。
try!:确定了不會有異常才能使用,不然系統會崩潰閃退。
我們可以使用
do-catch
捕獲異常,示例:
func TryExample() {
do {
try LoginError(username: nil)
} catch {
let err = error as? CustomNSError
print(err?.errorCode ?? "")
}
}
上述代碼中,我們定一個
TryExample
方法,我們使用
do-catch
語句運作一段閉包代碼來處理錯誤。
如果在
do
子句中的代碼抛出了
LoginError
錯誤,那麼我們會在
catch
子句進行處理。
我們這裡接收的錯誤是
LoginError
方法中
username
為空,處理的結果是列印輸出遵循
CustomNSError
協定的
AllError
的錯誤描述結果
404
。
本章代碼
import UIKit
enum AllError: Error {
case error1
case error2
case error3
}
extension AllError: LocalizedError {
var errorDescription: String? {
switch self {
case .error1:
return "第一個錯誤"
case .error2:
return "第二個錯誤"
case .error3:
return "第三個錯誤"
}
}
}
extension AllError: CustomNSError {
var errorCode: Int {
return 404
}
}
func LoginError(username: String?) throws {
if username == nil {
throw AllError.error1
} else {
print("username不為空")
}
}
func TryExample() {
do {
try LoginError(username: nil)
} catch {
let err = error as? CustomNSError
print(err?.errorCode ?? "")
}
}