Swift 2.0 異常處理

jopen 9年前發布 | 45K 次閱讀 Swift Apple Swift開發

 

Swift 2.0 異常處理

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

如何建造異常類型?

在 iOS 開發當中,我們會面對很多異常處理。在 Cocoa Touch 中我們使用 NSError 來進行異常處理。在新的 Swift 2.0 中,我們可以使用新的 ErrorType protocol。

在 Swift 中, enum 是最好的方法建立屬于你自己的異常類型,你只要在你的 enum 中確認新的 ErrorType。

enum MyError: ErrorType {  
  case NotExist
  case OutOfRange
}

如何拋出異常

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

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

聲明之后, 我們需要在函數或者方法里扔出異常,很簡單使用throw 就可以了

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

在 Haskell, Erlang 等語言中早已存在 guard, 在這里有更多關于它的介紹

guard 翻譯過來可以理解為守護,守衛。

在 Swift 中,guard 有點像 if 但是他們有兩個非常重要的區別

  • guard 必須強制有 else 語句

    </li>

  • 只有在 guard 審查的條件成立,guard 之后的代碼才會運行 (像守衛一樣,條件不符就不讓過去)。

    </li> </ul>

    guard 中的 else 只能執行轉換語句,像 return, break, continue 或者 throws 當然你也可以在這里返后一個函數或者方法。

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

    雖然我們在異常處理中提到了 guard 但是不代表它只能在異常處理中使用。它具有廣泛的適用性,或許過陣子我會專門為 guard的使用寫篇文章。

    如何獲取并處理異常?

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

     do {
        try functionWillThrowError()
      } catch {
        // deal with error
      }

    do-catch 機制簡單易懂。很多編程語言也使用類似的機制進行異常處理,但是在 Swift 中有一個比較重要的特性。

    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 機制

    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 的幫助建立你的異常類型

      </li>

    • 使用 throws 來聲明異常,用 throw 來拋出異常

      </li>

    • 使用 do-catch 機制來獲取和處理異常

      </li> </ul>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!