異常處理:
一眶拉、引入
二惹悄、異常表示
三她按、異常處理-4種方式
四阔挠、指定清理操作
涉及關(guān)鍵字:Error throw throws try do catch
引入
比如你設(shè)計(jì)的程序需要讀取電腦中的某個(gè)文件飘庄,以下代碼當(dāng)訪問(wèn)文件出現(xiàn)問(wèn)題時(shí),當(dāng)前沒(méi)法清楚的描述異常购撼,無(wú)法定位錯(cuò)誤的原因跪削。所以如何來(lái)描述異常呢?
func readFileContent(filePath : String) -> String? {
// 1.filePath為""
if filePath == "" {
return nil
}
// 2.filepath有值,但是沒(méi)有對(duì)應(yīng)的文件
if filePath != "/User/Desktop/123.plist" {
return nil
}
// 3.取出其中的內(nèi)容
return "123"
}
readFileContent(filePath: "abc")
在Swift里迂求,錯(cuò)誤用遵循 Error 協(xié)議的類型的值來(lái)表示;
Error是一個(gè)空的protocol碾盐,它唯一的功能,就是告訴Swift編譯器揩局,某個(gè)類型用來(lái)表示一個(gè)錯(cuò)誤毫玖。
通常,我們使用一個(gè)enum來(lái)定義各種錯(cuò)誤的可能性
拋出一個(gè)錯(cuò)誤用throw
通過(guò)合理定義異常凌盯,改進(jìn)上述代碼
// 1.定義異常
enum FileReadError : Error {
case FileISNull
case FileNotFound
}
// 2.改進(jìn)方法,讓方法拋出異常
func readFile(filePath : String) throws -> String {
// 1.filePath為""
if filePath == "" {
throw FileReadError.FileISNull
}
// 2.filepath有值,但是沒(méi)有對(duì)應(yīng)的文件
if filePath != "/User/Desktop/123.plist" {
throw FileReadError.FileNotFound
}
// 3.取出其中的內(nèi)容
return "123"
}
異常處理
拋出異常后付枫,也就是異常出現(xiàn)后,怎么處理呢驰怎?
用throwing 函數(shù)傳遞錯(cuò)誤
try?方式
最終返回結(jié)果為一個(gè)可選類型阐滩。如果出現(xiàn)了異常,則返回一個(gè)nil.沒(méi)有異常,則返回對(duì)應(yīng)的值——》不處理異常
try!方式
告訴系統(tǒng)該方法沒(méi)有異常,一旦如果出現(xiàn)了異常,則程序會(huì)直接崩潰
do catch(建議)
var result = try? readFile(filePath: "abc")
var result = try! readFile(filePath: "abc")
do{
try readFile(filePath: "abc")
}catch{//內(nèi)置變量error
print(error)
}
指定清理
在java中,我們處理異常使用 try catch finally 县忌。不管有沒(méi)有出錯(cuò)掂榔,我們一般把必須要執(zhí)行的代碼放在finally里。比較典型的一個(gè)場(chǎng)景是數(shù)據(jù)庫(kù)的操作症杏,不管是否操作成功装获,最后要close 釋放資源。
在swift中厉颤,如果想要defer語(yǔ)句來(lái)實(shí)現(xiàn)穴豫。
defer語(yǔ)句調(diào)用時(shí)機(jī):將離開(kāi)當(dāng)前代碼塊時(shí)執(zhí)行,可以用它在異常中進(jìn)行掃尾工作逼友,比如關(guān)閉IO流绩郎,釋放資源等
案例一:掌握defer執(zhí)行時(shí)機(jī)
do{
defer{
print("釋放資源11")
print("釋放資源12")
}
print("test1")
try readFile(filePath: "/User/Desktop/123.plist") //如果路徑為空,執(zhí)行順序如何翁逞?
print("test2")
}catch{//內(nèi)置變量error
print(error)
}
案例二:多個(gè)defer語(yǔ)句執(zhí)行順序
do{
defer{
print("釋放資源11")
print("釋放資源12")
print("釋放資源13")
}
defer{
print("釋放資源21")
}
defer{
print("釋放資源33")
}
try readFile(filePath: "/User/Desktop/123.plist")
}catch{//內(nèi)置變量error
print(error)
}