美文网首页swift
Swift基础10(Swift错误处理与异常抛出)

Swift基础10(Swift错误处理与异常抛出)

作者: SunshineBrother | 来源:发表于2020-01-27 17:50 被阅读0次

当我们在一个方法或函数中实现某些功能时,如果遇到错误的用户输入则可能导致严重的异常问题,此时我们可以选择通过抛出异常的方式。Swift 团队在 Swift 2 中包含了一种很好的方式来处理与理想情况的偏差。Swift Error Handling 能够让我们快速而简便的告知编译器一个函数能否抛出错误,并且在抛出后以合适的方式去处理错误

主动退出程序的几种情况

在程序运行到相关代码的时候,会直接退出程序

  • 1、Fatal Errors(致命的错误)
  • 2、Assertions(断言)
  • 3、先决条件(Preconditions)

1、Fatal Errors(致命的错误)

使用fatalError()函数可以立即终止你的应用程序,在fatalError()中可以给出终止信息。使用fatalError()函数,会毫无条件的终止你的应用程序,用起来也是比较简单的,就是一个函数的调用

fatalError("我是fatalError错误")
fatalError.png

2、Assertions(断言)

在单元测试中是少不了断言的,Swift中的断言和Objective-C的区别不是太大,使用方法也是大同小异。断言会在Debug模式下起作用,但是在Release版本中就会被忽略。

Assertions.png

在assert()函数中, 第一个参数是Bool类型,第二个参数是输出的信息。当条件为true时,断言不执行,相应的断言信息不打印。当条件为false时,断言执行,并且打印相应的断言信息。

assert(true, "我是true断言")
assert(false, "我是false断言")
assert.png

3、先决条件(Preconditions)

Preconditions的用法和断言一样,Preconditions在debug和release模式下都会被执行,除非使用–Ounchecked进行编译

Preconditions.png
precondition(true, "我是先决条件true")
precondition(false, "我是先决条件false")

Swift中的错误处理

1、使用枚举添加错误原因

定义错误类型

在 swift 中如果我们要定义一个表示错误的类型非常简单,只要遵循 Error 协议就可以了,我们通常用枚举或结构体来表示错误类型,枚举可能用的多些,因为它能更直观的表达当前错误类型的每种错误细节。

/// 定义一个枚举类型的错误类型
enum MyEnumError: Error {
    case ErrorReasonOne
    case ErrorReasonTwo
    case ErrorReasonThree
}

错误类型抛出

在我们的函数定义时可以使用throws关键字,以及在函数中使用throw关键字对错误进行抛出,抛出的错误类型就可以使用上面我们自己定义的错误类型

func testThrow(a:Int) throws {
        if a == 1 {
            throw MyEnumError.ErrorReasonOne
        }else if a == 2{
            throw MyEnumError.ErrorReasonTwo
        }else if a == 3{
            throw MyEnumError.ErrorReasonThree
        }
        print("正常流程")
    }

错误捕获与处理

上面函数的功能是对错误进行抛出,接下来就该使用do-catch来处理抛出的错误。使用try对错误进行捕捉,使用do-catch对错误进行处理。我们在catch的时候需要把每一种情况都列举出来。

do {
            try testThrow(a: 1)
        } catch MyEnumError.ErrorReasonOne {
            print("错误理由:ErrorReasonOne")
        }catch MyEnumError.ErrorReasonTwo {
            print("错误理由:ErrorReasonTwo")
        }catch MyEnumError.ErrorReasonThree {
            print("错误理由:ErrorReasonThree")
        }catch{
            print("其他错误")
        }

打印结果

错误理由:ErrorReasonOne

注意
只有抛出函数才能传递错误。任何在非抛出函数中抛出错误都必须在函数内部进行处理。

在枚举实现错误类型中我们可以通过值绑定的形式为错误添加错误代码和错误原因。

 /// 定义一个枚举类型的错误类型
    enum MyEnumError: Error {
        case ErrorState(errorCode:Int,errorMessage:String)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        
        do {
            try testThrow(a: 1)
        } catch MyEnumError.ErrorState(let code,let message) {
            print("错误码:\(code) 错误原因:\(message)")
        }catch{
            print("其他错误")
        }
    }
    func testThrow(a:Int) throws {
        if a == 1 {
            throw MyEnumError.ErrorState(errorCode: 404, errorMessage: "找不到服务器")
        }
        print("正常流程")
    }

打印结果

错误码:404 错误原因:找不到服务器

2、使用结构体为错误处理添加Reason

struct MyEnumError: Error {
        let reason : String
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        
        do {
            try testThrow(a: 1)
        } catch {
            print(error)
        }
    }
    func testThrow(a:Int) throws {
        if a == 1 {
            throw MyEnumError.init(reason: "404 找不到服务器")
        }
        print("正常流程")
    }

最后要对抛出的错误进行do-catch处理,在处理时,可以对错误原因进行打印,错误原因存储在error中,具体操作和打印结果如下所示:

MyEnumError(reason: "404 找不到服务器")

3、使String类型遵循ErrorType协议,直接使用String提供错误原因

extension String:Error{}

override func viewDidLoad() {
        super.viewDidLoad()
        
        do {
            try testThrow(a: 1)
        } catch {
            print(error)
        }
    }
    func testThrow(a:Int) throws {
        if a == 1 {
            throw "404 找不到服务器"
        }
        print("正常流程")
    }

4、try! try?

enum MyEnumError: Error {
    case ErrorState(errorCode:Int,errorMessage:String)
}


func divide(_ a:Int,_ b:Int) throws -> Int {
    if b == 0 {
       throw MyEnumError.ErrorState(errorCode: 100, errorMessage: "除数不能为0")
    }
    return a / b
}

let result1 = try? divide(10, 1)
let result2 = try? divide(10, 0)
print(result1,result2)

let result3 = try! divide(10, 2)
let result4 = try! divide(10, 0)
print(result3,result4)

打印结果

try

5、defer

defer语句:用来定义以任何方式(抛错误,return等)离开代码前必须执行的代码,defer语句将延迟至当前作用域之前执行

func test(){
    defer {
        print("打印defer")
    }
    do {
        let _ = try divide(10, 0)
    } catch let error {
        print(error)
    }
    
}
test()

550056DC-51C8-4786-828C-F8DEEC9DB622.png

参考

Swift 中的 Error Handling
错误处理
窥探Swift编程之错误处理与异常抛出

相关文章

  • Swift 中的异常抛出和错误处理

    Swift 中的异常抛出和错误处理

  • Swift基础10(Swift错误处理与异常抛出)

    当我们在一个方法或函数中实现某些功能时,如果遇到错误的用户输入则可能导致严重的异常问题,此时我们可以选择通过抛出异...

  • Swift3.x - 错误处理

    Swift异常错误处理:是响应错误以及从错误中恢复的过程。Swift提供了在运行时对可恢复错误的抛出、捕获、传递和...

  • Swift 错误处理、异常抛出

    前言    刚开始学习编程的时候,只考虑在对的情况下,该怎么去写我们的程序,但真正开始着手写项目程序时,在遇到异常...

  • Error Handing in swift3

    错误处理机制,在swift中的异常,必须在Controller级别给处理掉,不能再次往上抛出。 Handing E...

  • 《Swift从入门到精通》(十五):错误处理

    错误处理(学习笔记) 环境Xcode 11.0 beta4 swift 5.1 错误表现和抛出在 swift 中,...

  • swift异常处理

    swift像其他编程语言一样可以抛出异常并处理异常,本文就详细说一下在swift中抛出并处理异常,swift中的一...

  • Swift: 抛出异常

    很多代码都有try? 的关键字做法, 这是当有错误/无值的时候, 抛出异常。 这里用代码举例。 首先, 自定义一个...

  • Swift - 异常处理

    说明 跟其它语言一样,Swift的异常处理是在程序抛出异常后的处理逻辑。 Swift提供了一流的异常抛出、捕获和处...

  • Swift-异常处理四种方式

    跟其它语言一样,Swift的异常处理是在程序抛出异常后的处理逻辑。 Swift提供了一流的异常抛出、捕获和处理的能...

网友评论

    本文标题:Swift基础10(Swift错误处理与异常抛出)

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