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 控制语句捕获抛出的异常,进而作相关的逻辑处理。
相关文章
相关标签/搜索