美文网首页SwiftSwiftswift
swift异常处理(Error)

swift异常处理(Error)

作者: 三国韩信 | 来源:发表于2021-03-24 17:15 被阅读0次

    swift 是一个类型严格的语言,在很多情况下各种不匹配或者强制解包出错都会导致系统崩溃。所以我们需要进行异常处理,在swift中也叫错误处理Error。

    Swift中可以通过Error协议自定义运行时的错误信息。在开发中常常也和枚举enum一起使用。Error协议其实是个空协议。比如这样定义error枚举

    enum MyError: Error {
      case error1((Int,String))
      case error2((Int,String))
      case error3((Int,String))
    }
    

    对于有可能崩溃的代码,在swift中可以通过throws关键来抛出错,给调用方去处理异常。如果没人处理,最终会导致App崩溃闪退。
    对于有throws关键字的函数,调用的时候要加try关键字。

    // 通过关键字throws来抛出错误。
    // 这个函数num2为0的时候会崩溃的,除数不能为0
    func divNum(_ num1: Int, _ num2: Int) throws -> Int {
        let result = num1 / num2  
        return result
    }
    // 对于有throws关键字的函数,调用的时候要加try
    try divNum(10,20)
    
    捕捉Error

    在swift中,可以使用do-catch捕捉Error。比如下面的例子,通过do-catch去捕获异常,最终会执行catch中的代码。

    enum netWorkError: Error {
        case businessError(code: Int, msg: String)
        case systemError(msg: String)
    }
    
    func divNum(_ num1: Int, _ num2: Int) throws -> Int {
        if num2 == 0 {
            throw netWorkError.businessError(code: 300, msg: "除数不能为0")
        }
        let result = num1 / num2
        return result
    }
    
    do{
        let num = divNum(100,0)   // 这一句会发生异常
        print(num)    
    }catch {
        print("Error") // 会执行这一句
    }
    
    
    处理Error

    在swift中,处理Error的3种方式:
    1、通过do-catch捕捉Error,然后处理Error(一般是和定义的枚举结合,通过switch来处理)。

    do{
        let num = try divNum(100, 0)
        print(num)
    }catch let error as netWorkError {
        switch error {
            case .businessError(code: 300, msg: "除数不能为0"):
                print("确认---除数不能为0")
            case .businessError(let code,let msg):
                print(code,msg)
            case .systemError(let systemMsg):
                print("systemError:",systemMsg)
            default:
                print("other MyError")
        }
    }catch {
        print("other UnKnow Error")
    }
    

    2、不捕捉Error,在当前函数增加throws声明,Error将自动抛给上层函数。如果最终没人处理,系统一样会崩溃闪退。

    
    enum netWorkError: Error {
        case businessError(code: Int, msg: String)
        case systemError(msg: String)
    }
    
    func divNum(_ num1: Int, _ num2: Int) throws -> Int {
        if num2 == 0 {
            throw netWorkError.businessError(code: 300, msg: "除数不能为0")
        }
        let result = num1 / num2
        return result
    }
    
    // noHandlerError函数声明了throws,一样没有处理异常,只是往上抛出,看有没有人去处理。
    func noHandlerError() throws {
        let num = try divNum(100, 0)
        print(num)
    }
    
    

    3、通过使用try?、try!调用可能会抛出Error的函数,这样就不用去处理Error。当调用的函数抛出异常是得到的结果就是nil,如果正常,则返回一个可选项。

    enum netWorkError: Error {
        case businessError(code: Int, msg: String)
        case systemError(msg: String)
    }
    
    func divNum(_ num1: Int, _ num2: Int) throws -> Int {
        if num2 == 0 {
            throw netWorkError.businessError(code: 300, msg: "除数不能为0")
        }
        let result = num1 / num2
        return result
    }
    
    // 通过try?来调用,返回num是nil
    var num = try? divNum(100, 0)
    print(num)
    
    // 其实try?等价于下面代码的
    var a: Int?
    do {
      a = try divNum(100, 0)
    }catch {
      a = nil 
    }
    
    
    rethrows

    rethrows表明:函数本身不会抛出错误,但调用闭包参数抛出错误,那么它会将错误向上抛。
    rethrows主要用于参数有闭包的时候,闭包本身会有抛出异常的情况。
    rethrows作为一个标志,显示的要求调用者去处理这个异常(不处理往上抛)。

    
    func divNum(_ num1: Int, _ num2: Int) throws -> Int {
        if num2 == 0 {
            throw netWorkError.businessError(code: 300, msg: "除数不能为0")
        }
        let result = num1 / num2
        return result
    }
    
    func exec(num1: Int, num2: Int, fn: (Int, Int) throws -> Int) rethrows {
       print(try? fn(num1,num2)) // 这里因为fn函数有throws标志,必须用try处理异常
    }
    
    // 这里因为exec函数有rethrows标志,所以也必须用try去处理异常
    try exec(num1: 100, num2: 200, fn: divNum)
    
    

    相关文章

      网友评论

        本文标题:swift异常处理(Error)

        本文链接:https://www.haomeiwen.com/subject/rkslcltx.html