Swift 異常處理

前言

  • 在 Swift 1.0 時代是沒有異常處理和拋出機制的。編程

    • 若是要處理異常,要麼使用 if else 語句或 switch 語句判斷處理。
    • 要麼使用閉包形式的回調函數處理。
    • 再要麼就使用 NSError 處理。
  • 以上這些方法都不能像 Java 中的 try catch 異常控制語句那樣行如流水、從容不迫的處理異常,並且也會下降代碼的可讀性。swift

  • 在 Swift 2.0 中 Apple 提供了使用 throwsthrowtrydocatch 這五個關鍵字組成的異常控制處理機制。微信

一、建造異常類型

  • 在 iOS 開發當中,咱們會面對不少異常處理。網絡

    • 在 Cocoa Touch 中使用 Error 來進行異常處理。
    • 從 Swift 2.0 開始,可使用 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 中有一個比較重要的特性。catchswitch 同樣具備模式匹配(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 控制語句捕獲拋出的異常,進而作相關的邏輯處理。
相關文章
相關標籤/搜索