在 Swift 1.0 時代是沒有異常處理和拋出機制的。編程
if else
語句或 switch
語句判斷處理。NSError
處理。以上這些方法都不能像 Java 中的 try catch
異常控制語句那樣行如流水、從容不迫的處理異常,並且也會下降代碼的可讀性。swift
在 Swift 2.0 中 Apple 提供了使用 throws
、throw
、try
、do
、catch
這五個關鍵字組成的異常控制處理機制。微信
在 iOS 開發當中,咱們會面對不少異常處理。網絡
Error
來進行異常處理。Error protocol
。在 Swift 中,enum 是創建屬於你本身的異常類型的最好的方法,你只要在你的 enum 中確認新的 Error
。閉包
enum MyError: Error { case notExist case outOfRange }
在拋出異常以前,咱們須要在函數或方法的返回箭頭 ->
前使用 throws
關鍵字來標明將會拋出異常。編程語言
// 有返回值,在 -> 前加 throws func myMethodRetrunString() throws -> String // 聲明將會拋出異常 // 沒有返回值,在方法末尾加 throws func myMethodRetrunNothing() throws // 聲明將會拋出異常
聲明以後,在函數或者方法裏使用 throw
關鍵字扔出異常,throw
以後的代碼不會再被執行。函數
func myMethodRetrunNothing() throws { // ... // item is an optional value guard let item = item else { // need throws the error out throw MyError.notExist // 拋出異常 } // do with item }
Swift 中使用 try-catch
機制獲取和處理異常。code
do { try 可拋出異常的方法或函數 } catch { // 處理異常狀況,默認錯誤對象 error }
在 catch {}
中,不須要顯示的指定錯誤對象,你會默認捕獲一個錯誤對象 error
,若是你想替換這個名字,可使用 cache (let aError) {}
便可。對象
do { try 可拋出異常的方法或函數 } catch (let aError) { // 處理異常狀況,錯誤對象 aError }
try-catch
機制簡單易懂,不少編程語言也使用相似的機制進行異常處理,可是在 Swift 中有一個比較重要的特性。catch
和 switch
同樣具備模式匹配(Pattern Matching)的能力,因此使用 catch
時能夠對異常的解析進行更爲高級的處理。開發
do { try myMethodRetrunNothing() } catch MyError.notExist { // deal with not exist } catch MyError.outOfRange { // deal with out of range } catch { // deal with other error }
和可選型相似,編譯器強制咱們在使用可能拋出錯誤的方法時使用 try
關鍵字,既可使用完整的 try-catch
捕獲,也可使用 try?
和 try!
。
try?
有點相似於可選型中的可選鏈,若是方法正確,則徹底執行,若是拋出錯誤,則方法提早結束,但不會對拋出的錯誤進行處理。try!
的用法相似於可選型中的強制解包,一樣不會對錯誤進行處理,可是一旦方法拋出錯誤,就會形成整個程序的崩潰。try? myMethodRetrunNothing() try! myMethodRetrunNothing()
Error
的幫助創建你的異常類型。throws
來聲明異常,用 throw
來拋出異常。使用 try-catch
機制來獲取和處理異常。
下面來舉例看看如何使用,用使用手機刷朋友圈爲例。首先咱們須要定義異常枚舉,從 Swift 2.0 中開始 Apple 提供了 Error
協議,咱們自定義的異常枚舉須要遵循
// 定義異常枚舉 enum WechatError: Error { case noBattery // 手機沒電 case noNetwork // 手機沒網 case noDataStream // 手機沒有流量 }
咱們定義了致使不能刷微信的錯誤枚舉 WechatError
,而後定義一個檢查是否能夠刷微信的方法 checkIsWechatOk()
// 定義異常拋出方法 func checkIsWechatOk(isPhoneHasBattery: Bool, isPhoneHasNetwork: Bool, dataStream: Int) throws { guard isPhoneHasBattery else { throw WechatError.noBattery } guard isPhoneHasNetwork else { throw WechatError.noNetwork } guard dataStream > 50 else { throw WechatError.noDataStream } }
在方法名後有 throws
關鍵字,意思爲該方法產生的異常向上層拋出,在方法體內使用 guard
語句對各類狀態進行判斷,而後使用 throw
關鍵字拋出對應的異常。而後咱們定義刷微信的方法。
// 定義刷微信的方法 func playWechat(isPhoneHasBattery: Bool, isPhoneHasNetwork: Bool, dataStream: Int) { do { try checkIsWechatOk(isPhoneHasBattery: isPhoneHasBattery, isPhoneHasNetwork: isPhoneHasNetwork, dataStream: dataStream) print("放心刷,刷到天昏地暗!") } catch WechatError.noBattery { print("手機都沒電,刷個鬼啊!") } catch WechatError.noNetwork { print("沒有網絡哎,洗洗玩單機吧!") } catch WechatError.noDataStream { print("沒有流量了,去蹭Wifi吧!") } catch { print("見鬼了!") } } playWechat(isPhoneHasBattery: true, isPhoneHasNetwork: true, dataStream: 60) // 放心刷,刷到天昏地暗! playWechat(isPhoneHasBattery: true, isPhoneHasNetwork: false, dataStream: 60) // 沒有網絡哎,洗洗玩單機吧! playWechat(isPhoneHasBattery: false, isPhoneHasNetwork: true, dataStream: 60) // 手機都沒電,刷個鬼啊! playWechat(isPhoneHasBattery: true, isPhoneHasNetwork: true, dataStream: 30) // 沒有流量了,去蹭Wifi吧!
try
關鍵字,表示容許該方法拋出異常,而後使用了 do catch
控制語句捕獲拋出的異常,進而作相關的邏輯處理。