美文网首页
Swift-错误处理

Swift-错误处理

作者: Sweet丶 | 来源:发表于2022-08-16 00:28 被阅读0次
Swift错误处理.png
一、Swift中抛出自定义Error

有时定义一个方法,这个方法在执行的过程中可能会抛出异常,这个时候需要向调用者抛出,让调用者来具体处理,比如系统的JSONSerialization.jsonObject方法。下面是一个抛出自定义异常的例子:

// 1.先自定义一个错误类型,类型需要遵守Error协议,比如自定义枚举。
enum SomeError : Error {
    case illegalArg(String)
    case outOfBounds(Int, Int)
    case outOfMemory
}

// 2. 在会抛出错误的方法中声明throws,并且在需要的地方抛出对应的错误
/// 自定义Error的抛出
static func divide_error(_ v1: Int, _ v2: Int) throws -> Int {
    if v2 == 0 {
        throw SomeError.illegalArg("0不能作为除数")
    }else if v1 < v2 {
        throw SomeError.outOfBounds(v1, v2)
    }else if v1 > Int8.max || v2 > Int8.max{// 大于Int8以上的数据不作除法
        throw SomeError.outOfMemory
    }else{
        return v1/v2
    }
}

/// 如果调用divide_error的地方对于抛出的错误不catch,那么会向上一级作用域抛出,
/// 如果直到系统main函数都未catch,那么会发生闪退fatal error.

// 3. 调用会抛出异常的方法一
do {
    let result1 = try divide_error(10, 5)
//  let result2 = try divide_error(10, 0)
//  let result3 = try divide_error(10, 20)
//  let result4 = try divide_error(Int.max, 50)
} catch SomeError.outOfMemory {
    print("捕获到了超出最大值的异常")
} catch SomeError.illegalArg(let errorMsg){
    print(errorMsg)
} catch let SomeError.outOfBounds(num1, num2){
    print("除数大于被除数:num1=\(num1), num2 =\(num2)")
} catch {
    print("其它异常")
}
二、将错误抛出给上一级调用者处理

如果在调用方法时,不能确定抛出错误的具体处理,而是要在上一层调用才能明确,这个时候可以将错误继续向上一层抛出,如果直到系统main函数都未catch,那么会发生闪退fatal error. 具体写法:

// 4. 调用上述会抛出异常的方法二: 将错误向上抛出
// 在设计一个方法时,方法内部调用了会抛出异常的方法,
// 但是抛出的这个异常的处理是希望使用者来决定,
// 这个时候就可以继续向上抛出,即自己的方法写上throws,调用时不do...catch
func test1() throws {
    let result1 = try divide_error(10, 5)
}

func test0() throws {
    let result1 = try test1()
}

// 程序员在外部调用方法负责去catch
do {
    try test0()
} catch is SomeError {
    print("SomeError")
}
三、try?、try!

使用try?try!来调用可能抛出错误的函数时,可以不向上抛出或者不使用do...catch

// 方式一
var a = try? divide_error(10, 0)
// 方式二:等价于方式一
var b: Int?
do {
    b = try divide_error(10, 0)
} catch {}
// a和b的值都是nil
// 方式三:使用try!, 效果是对try?的结果强制解包,有crash风险
四、rethrows

如果函数的一个参数是可能抛出错误的闭包,那么这个时候函数想将错误抛出,需要用rethrows表明。

/// 这个是系统的空合并运算符的定义
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
五、defer

这个关键字用来定义以任何形式(包括抛出错误、return)离开代码块前都要执行的语句, 程序发生crash不算,因为crash时已经是停在某行代码了,无法继续运行。

func test() throws {
    defer {
        print("defer1----")
    }
    // 多个defer时,打印是defer2在前
    defer {
        print("defer2----")
    }
    // return
    var a = try divide_error(10, 0) 
}
六、assert、fatalError

assert:一般用于debug阶段,在运行时抛出不符合条件的错误。在release模式下会直接失效。
fatalError:直接抛出错误,让程序崩溃。

    // 第一个参数表示
    assert(delegate != nil, "NetWorkConfig setDelegate success")
    
    // 自定义view时,必须实现的方法
    public required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

相关文章

网友评论

      本文标题:Swift-错误处理

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