錯誤分為可恢復的錯誤和不可恢復的錯誤梅肤,可恢復的錯誤指的是能預見并處理的錯誤聂示,例如文件不存在它掂,網(wǎng)絡連接失敗等彬檀;不可恢復的錯誤指的是一類特殊的bug帆啃,例如強制展開值為nil的可空實例,數(shù)組越界訪問等窍帝;如果發(fā)生錯誤沒有處理努潘,程序就會停止運行。遺憾的是Swift中似乎只能處理可恢復的錯誤。
斷言
Swift中使用assert添加斷言慈俯,第一個參數(shù)表示要檢查的條件渤刃,為true時什么也不做,為false時停止運行并顯示錯誤信息贴膘;第二個參數(shù)為檢查條件為false時輸出的字符串信息卖子,默認為空;最后兩個參數(shù)為調用assert所在的源文件名刑峡,行號洋闽。
/// - Parameters:
/// - condition: The condition to test. `condition` is only evaluated in
/// playgrounds and `-Onone` builds.
/// - message: A string to print if `condition` is evaluated to `false`. The
/// default is an empty string.
/// - file: The file name to print with `message` if the assertion fails. The
/// default is the file where `assert(_:_:file:line:)` is called.
/// - line: The line number to print along with `message` if the assertion
/// fails. The default is the line number where `assert(_:_:file:line:)`
/// is called.
public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)
assert只有在調試模式才有效,要想在發(fā)布模式也生效可以使用precondition突梦,兩者用法相同
var number1=1
assert(number1 != 1,"number1 is 1")
precondition(number1 != 1,"number1 is 1")
拋出錯誤
遇到錯誤時诫舅,可以使用throw拋出一個符合Error協(xié)議的類型的實例,由于Error協(xié)議是一個空協(xié)議宫患,所以不需要任何屬性或方法刊懈,就能實現(xiàn)Error協(xié)議。如果該錯誤沒有被處理娃闲,則會停止運行虚汛,例如下面的代碼。
import Foundation
struct XYError:Error{
}
throw XYError()
捕捉錯誤
Swift中使用do...catch捕捉拋出的錯誤皇帮,如果沒有指定錯誤類型則會捕捉所有錯誤
import Foundation
struct XYError:Error{
}
do{
throw XYError()
}catch{
print("error")
}
也可以捕捉多個錯誤
import Foundation
enum NetError:Error{
case serverError
}
struct XYError:Error{
var errorType:Int
}
do{
throw XYError(errorType:3)
throw NetError.serverError
}catch NetError.serverError{
print("net error")
}catch let e as NetError{
print("net error \(e)")
}catch let e as XYError{
print(e.errorType)
}catch{
print("error")
}
可拋出錯誤的函數(shù)
在函數(shù)簽名后面加上throws表示該函數(shù)可能會拋出錯誤卷哩,調用此函數(shù)時前面必須加上try,并且需要把調用此函數(shù)寫在do...catch內属拾。
func makeError(arg:Int) throws->Int{
guard arg > 10 else {
throw XYError(errorType:3)
}
return arg
}
//編譯會報錯
func testFunc(){
try makeError(arg: 1)
}
//正確寫法
func testFunc(){
do{
try makeError(arg: 1)
}catch{
print("error")
}
}
如果調用可拋出錯誤的函數(shù)的函數(shù)也標記為throws将谊,那么該函數(shù)可以不處理錯誤,錯誤將再次拋出
func makeError(arg:Int) throws->Int{
guard arg > 10 else {
throw XYError(errorType:3)
}
return arg
}
func testFunc() throws{
try makeError(arg: 1)
}
調用可拋出錯誤的函數(shù)的函數(shù)也可以使用try!告訴編譯器不想處理潛在錯誤渐白,出現(xiàn)錯誤時停止運行
func makeError(arg:Int) throws->Int{
guard arg > 10 else {
throw XYError(errorType:3)
}
return arg
}
func testFunc() {
try! makeError(arg: 1)
}
try還有另外一種變體try?尊浓,可以在發(fā)生錯誤時忽略錯誤,但不會停止運行而是返回原本返回值的可空類型
func makeError(arg:Int) throws->Int{
guard arg > 10 else {
throw XYError(errorType:3)
}
return arg
}
func testFunc() {
print(try? makeError(arg: 1))
}