• Swift 异常处理


    前言

    • 在 Swift 1.0 时代是没有异常处理和抛出机制的。

      • 如果要处理异常,要么使用 if else 语句或 switch 语句判断处理。
      • 要么使用闭包形式的回调函数处理。
      • 再要么就使用 NSError 处理。
    • 以上这些方法都不能像 Java 中的 try catch 异常控制语句那样行如流水、从容不迫的处理异常,而且也会降低代码的可读性。

    • 在 Swift 2.0 中 Apple 提供了使用 throwsthrowtrydocatch 这五个关键字组成的异常控制处理机制。

    1、建造异常类型

    • 在 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                 // 声明将会抛出异常
      

    2、抛出异常

    • 声明之后,在函数或者方法里使用 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
      }
      

    3、获取并处理异常

    • Swift 中使用 try-catch 机制获取和处理异常。

      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
      }
      

    4、不处理异常

    • 和可选型类似,编译器强制我们在使用可能抛出错误的方法时使用 try 关键字,既可以使用完整的 try-catch 捕获,也可以使用 try?try!

      • try? 有点类似于可选型中的可选链,如果方法正确,则完全执行,如果抛出错误,则方法提前结束,但不会对抛出的错误进行处理。
      • try! 的用法类似于可选型中的强制解包,同样不会对错误进行处理,但是一旦方法抛出错误,就会造成整个程序的崩溃。
      try? myMethodRetrunNothing()
      
      try! myMethodRetrunNothing()
      

    5、总结

    • 使用 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 控制语句捕获抛出的异常,进而做相关的逻辑处理。
  • 相关阅读:
    vue实战使用ajax请求后台数据(小白)
    jQuery实现tab栏切换效果
    jQuery下的ajax实例
    数据库之视图更新
    SQL Server 全文索引创建
    SQL Server 分区表
    数据快照 (Database Snapshot)
    FileStream
    ODBC,OLEDB,ADO,ADO.net,JDBC 理解
    拖延症?贪玩?来试试"百万金币时间管理法"
  • 原文地址:https://www.cnblogs.com/QianChia/p/8670872.html
Copyright © 2020-2023  润新知