如何建造異常類型? html
在 iOS 開發當中,咱們會面對不少異常處理。在 Cocoa Touch 中咱們使用 NSError 來進行異常處理。在新的 Swift 2.0 中,咱們可使用新的 ErrorType protocol。 ios
在 Swift 中, enum 是最好的方法創建屬於你本身的異常類型,你只要在你的 enum 中確認新的 ErrorType。 編程
1
2
3
4
|
enum MyError: ErrorType {
case NotExist
case OutOfRange
}
|
如何拋出異常 swift
在拋出異常以前,咱們須要在函數或方法的返回箭頭 -> 前使用 throws 來標明將會拋出異常 app
1
2
3
|
func myMethodRetrunString() throws -> String
// No return, we can just add throws in the end
func myMethodRetrunNothing() throws
|
聲明以後, 咱們須要在函數或者方法裏扔出異常,很簡單使用throw 就能夠了 編程語言
1
2
3
4
5
6
7
8
9
|
func myMethod() throws
//...
// item is an optional value
guard let item = item else {
// need throws the error out
throw MyError.NotExist
}
// do with item
}
|
上面這段代碼使用了 guard 來進行unwrap optional value。這是 Swift 2.0 提供的一個新的方法。 函數
Guard spa
在 Haskell, Erlang 等語言中早已存在 guard, 在這裏有更多關於它的介紹。 翻譯
guard 翻譯過來能夠理解爲守護,守衛。 htm
在 Swift 中,guard 有點像 if 可是他們有兩個很是重要的區別
guard 必須強制有 else 語句
只有在 guard 審查的條件成立,guard 以後的代碼纔會運行 (像守衛同樣,條件不符就不讓過去)。
guard 中的 else 只能執行轉換語句,像 return, break, continue 或者 throws 固然你也能夠在這裏返後一個函數或者方法。
值得注意的是,guard的使用會提升你代碼的可讀性,可是也表明你的代碼的執行會有很是明確的順序性,這一點須要開發者們留心處理。
雖然咱們在異常處理中提到了 guard 可是不表明它只能在異常處理中使用。它具備普遍的適用性,或許過陣子我會專門爲 guard的使用寫篇文章。
如何獲取並處理異常?
上文講述瞭如何建造拋出異常,獲取和處理異常就變得很簡單了。使用 do-catch 機制。
1
2
3
4
5
|
do {
try functionWillThrowError()
} catch {
// deal with error
}
|
do-catch 機制簡單易懂。不少編程語言也使用相似的機制進行異常處理,可是在 Swift 中有一個比較重要的特性。
catch 和 switch 同樣具備 Pattern Matching 的能力。因此,使用 catch 你能夠對異常的解析進行更爲高級的處理
1
2
3
4
5
6
7
|
do {
try functionWillThrowError()
} catch MyError.NotExist {
// deal with not exist
} catch MyError.OutOfRange {
// deal with not exist
}
|
這裏值得提一下在 Swift 2.0中一個跟異常處理沒有關係的改進
Swift 2.0 中沒有了 do-while循環,取而代之的是 repeat-while。蘋果說這個改動是爲了加強代碼的可讀性。可是我更以爲是爲了讓咱們更舒服的使用 do-catch
不處理異常
若是我不想處理異常怎麼辦,或者說,我很是肯定某個方法或者函數雖然聲明會拋出異常,可是我本身知道我在使用時候是絕對不會拋出任何異常的。這種狀況下 咱們可使用 try!
1
|
try! functionThrowErrorNil()
|
固然,若是你使用 try!,而你的方法或者函數拋出了異常,那麼你會獲得一個運行中異常 (runtime error) 因此咱們開發者須要慎用哦。
Defer
文章結束前咱們再討論下 defer
在你的代碼塊就要結束前。若是你使用了 defer。 在其之中的代碼就會運行。等於說,給了你最後的機會來進行一些處理。若是你熟悉 BDD 或者 TDD, 那麼你能夠參考他們中的 aferAll 機制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
func myFunction() throws {
defer {
// No matter what happened I need do something
print("All done, clean up here")
}
guard let item = item else {
// need throws the error out
throw MyError.NotExist
}
guard item.count > maxNumber else {
// need throws the error out
throw MyError.OutOfRange
}
// do something with item
// ...
}
|
注意,若是你有多個defer 語句,他們在執行的順序會和棧同樣,最後一個進,第一個出。
總結
使用 ErrorType 的幫助創建你的異常類型
使用 throws 來聲明異常,用 throw 來拋出異常
使用 do-catch 機制來獲取和處理異常