Swift 2.0 異常處理

轉自:http://www.jianshu.com/p/96a7db3fde00html

WWDC 2015 宣佈了新的 Swift 2.0. 此次重大更新給 Swift 提供了新的異常處理方法。這篇文章會主要圍繞這個方面進行討論。ios

如何建造異常類型?

在 iOS 開發當中,咱們會面對不少異常處理。在 Cocoa Touch 中咱們使用 NSError 來進行異常處理。在新的 Swift 2.0 中,咱們可使用新的 ErrorType protocol。編程

在 Swift 中, enum 是最好的方法創建屬於你本身的異常類型,你只要在你的 enum 中確認新的 ErrorTypeswift

enum MyError: ErrorType {  
  case NotExist
  case OutOfRange
}

如何拋出異常

在拋出異常以前,咱們須要在函數或方法的返回箭頭 -> 前使用 throws 來標明將會拋出異常bash

func myMethodRetrunString() throws -> String // No return, we can just add throws in the end func myMethodRetrunNothing() throws

聲明以後, 咱們須要在函數或者方法裏扔出異常,很簡單使用throw 就能夠了app

func myMethod() throws
  //...
  // item is an optional value
  guard let item = item else {
    // need throws the error out
    throw MyError.NotExist
  }
  // do with item
}

 

上面這段代碼使用了  來進行unwrap optional value。這是 Swift 2.0 提供的一個新的方法。guard

Guard

在 Haskell, Erlang 等語言中早已存在 guard, 在這裏有更多關於它的介紹編程語言

guard 翻譯過來能夠理解爲守護,守衛。函數

在 Swift 中,guard 有點像 if 可是他們有兩個很是重要的區別spa

  • guard 必須強制有 else 語句
  • 只有在 guard 審查的條件成立,guard 以後的代碼纔會運行 (像守衛同樣,條件不符就不讓過去)。

guard 中的 else 只能執行轉換語句,像 returnbreakcontinue 或者 throws 固然你也能夠在這裏返後一個函數或者方法。翻譯

值得注意的是,guard的使用會提升你代碼的可讀性,可是也表明你的代碼的執行會有很是明確的順序性,這一點須要開發者們留心處理。

雖然咱們在異常處理中提到了 guard 可是不表明它只能在異常處理中使用。它具備普遍的適用性,或許過陣子我會專門爲 guard的使用寫篇文章。

如何獲取並處理異常?

上文講述瞭如何建造拋出異常,獲取和處理異常就變得很簡單了。使用 do-catch 機制。

do {
    try functionWillThrowError()
  } catch {
    // deal with error
  }
 機制簡單易懂。不少編程語言也使用相似的機制進行異常處理,可是在 Swift 中有一個比較重要的特性。do-catch

catch 和 switch 同樣具備 Pattern Matching 的能力。因此,使用 catch 你能夠對異常的解析進行更爲高級的處理

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!

try! functionThrowErrorNil()

固然,若是你使用 try!,而你的方法或者函數拋出了異常,那麼你會獲得一個運行中異常 (runtime error) 因此咱們開發者須要慎用哦。

Defer

文章結束前咱們再討論下 defer

在你的代碼塊就要結束前。若是你使用了 defer。 在其之中的代碼就會運行。等於說,給了你最後的機會來進行一些處理。若是你熟悉 BDD 或者 TDD, 那麼你能夠參考他們中的 aferAll 機制

文/阮超(簡書做者)
原文連接:http://www.jianshu.com/p/96a7db3fde00
著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。

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 機制來獲取和處理異常
相關文章
相關標籤/搜索