Files
knowledge-kit/Chapter1 - iOS/1.118.md
2024-04-27 13:01:58 +08:00

137 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Swift 错误处理
```swift
enum SomeError: Error {
case illegalArg(String)
case outOfBounds(Int, Int)
case outOfMemory
}
func divide(_ num1: Int, _ num2: Int) throws -> Int {
if num2 == 0 {
throw SomeError.illegalArg("分母不能为0")
}
return num1/num2
}
func testErrorCapture() {
print("1")
do {
print("2")
print(try divide(20, 0))
print("3")
} catch let SomeError.illegalArg(msg) {
print("参数异常:", msg)
} catch let SomeError.outOfBounds(size, index) {
print("下标越界: size = \(size), index = \(index)")
} catch SomeError.outOfMemory {
print("内存溢出")
} catch {
print("其他异常")
}
print("4")
}
testErrorCapture()
// console
1
2
0
4
```
如果 `try divide(20, 0)` 则输出: 1 、2、参数异常 分母不能为0、4
如果 `try divide(20, 2)` 则输出: 1 、2、10、3、4
说明:如果 do 抛出异常,则作用域内的后续的其他代码都不会被执行
## Error 处理方式
- 通过 do-catch 捕捉 Error
- 不捕捉 Error在当前函数增加 throws 声明Error 继续向上层调用函数抛
```swift
func divide(_ num1: Int, _ num2: Int) throws -> Int {
if num2 == 0 {
throw SomeError.illegalArg("分母不能为0")
}
return num1/num2
}
func safeDivide(_ num1: Int, _ num2: Int) -> Int {
var result:Int = 0
do {
result = try divide(num1, num2)
} catch let SomeError.illegalArg(msg) {
print("参数异常:", msg)
} catch let SomeError.outOfBounds(size, index) {
print("下标越界: size = \(size), index = \(index)")
} catch SomeError.outOfMemory {
print("内存溢出")
} catch {
print("其他异常")
}
return result
}
print("1")
print(safeDivide(8, 2))
print("3")
// console
1
4
3
```
- 如果有些错误不需要向上抛,可以用 `try?` ` try!` 调用可能会抛出 Error 的函数,这样就不需要去处理 Error
```swift
func testIgnoreError () {
print("1")
print(try? divide(10, 0))
print("2")
}
testIgnoreError()
// console
1
nil
2
```
## rethrows
如果一个函数本身不会抛出错误,但某个参数是闭包,且闭包抛出错误,那么函数需要用 `rethrows` 向上抛出错误
```swift
func exec(_ fn: (Int, Int) throws -> Int, _ num1: Int, _ num2: Int) rethrows {
print(try fn(num1, num2))
}
func testCaptureClouserError () {
do {
try exec(divide, 20, 0)
} catch let error {
switch error {
case let SomeError.illegalArgs(msg):
print("参数异常:", msg)
break
case let SomeError.outOfBounds(size, index):
print("下标越界: size = \(size), index = \(index)")
break
case SomeError.outOfMemory :
print("内存溢出")
break
default:
print("其他异常")
}
}
}
testCaptureClouserError() // 参数异常: 分母不能为0
```