美文网首页
Swift异常处理(Error) — do try catch机

Swift异常处理(Error) — do try catch机

作者: 雪碧童鞋 | 来源:发表于2022-03-07 16:21 被阅读0次

Swift提供Error协议来表示当前应用程序发生的错误情况,Error的定义如下:

public protocol Error : Sendable {
}

所以StructClassEnum都可以通过遵守这个协议来表示一个错误,一般情况下偏向于用Enum来表示错误。

1. 定义异常枚举
  • 定义

    enum JSONMapError: Error {
        case emptyKey           // key为空
        case notConformProtocol // 没有遵守协议
    }
    
  • 当需要抛出详细的错误信息时,可以让错误枚举遵守LocalizedError协议,协议内容如下:

    public protocol LocalizedError : Error {
        /// A localized message describing what error occurred.
        var errorDescription: String? { get }
    
        /// A localized message describing the reason for the failure.
        var failureReason: String? { get }
    
        /// A localized message describing how one might recover from the failure.
        var recoverySuggestion: String? { get }
    
        /// A localized message providing "help" text if the user requests help.
        var helpAnchor: String? { get }
    }
    

    示例:

    extension JSONMapError: LocalizedError{
        var errorDescription: String?{
            switch self {
            case .emptyKey:
                return "key为空"
            case .notConformProtocol:
               return "没有遵守协议"
            }
        }
    }
    
  • 当我们需要自定义错误信息的时候,可以让错误枚举类型遵守CustomNSError协议,协议内容如下:

    public protocol CustomNSError : Error {
        /// The domain of the error.
        static var errorDomain: String { get }
        /// The error code within the given domain.
        var errorCode: Int { get }
        /// The user-info dictionary.
        var errorUserInfo: [String : Any] { get }
    }
    

    示例:

    extension JSONMapError: CustomNSError{
        var errorCode: Int{
            return 404
        }
    }
    
2.错误的抛出

当需要抛出错误的时候,使用 throw 关键字将 Error 类型的错误抛出,同时使用throw关键字,则方法声明中就必须使用 throws 来接受错误,例如:

func test(name: String?) throws {
    if name == nil {
        throw JSONMapError.emptyKey
    } else {
        print("name不为空")
    }
}
3.捕获错误

Swift中错误的集中处理方式:

  • 使用try关键字
    • try果发生错误,会向上层抛出,如果一直没有处理就会到main函数,还是没有处理就会崩溃
    • try?返回的是一个可选类型,成功返回具体的值,错误则返回nil
    • try!确认不会有异常,如果有异常就直接崩溃
  • 使用 do...catch
// 使用上面的例子演示错误的捕获
func testExample() {
    //示例一
    do {
       try test(name: nil)
    } catch {
        let err = error as? LocalizedError
        print(err?.errorDescription ?? "")
    }
  
    //示例2
  do {
       try test(name: nil)
    } catch JSONMapError.emptyKey {
        print("key为空")
    }catch JSONMapError.notConformProtocol{
        print("没有遵守协议")
    } catch {
        print("unKnown Error")
    }
}

举个字典转模型中常见的错误捕捉例子

protocol CustomJSONMap{
    func jsonMap() throws -> Any
}

extension CustomJSONMap{
    func jsonMap() throws -> Any{
         //Mirror反射,下个章节介绍
        let mirror = Mirror(reflecting: self)
        // 中断递归的条件
        guard !mirror.children.isEmpty else {return self}

        var keyValue: [String: Any] = [:]
        for children in mirror.children{
            if let value = children.value as? CustomJSONMap{
                if let keyName = children.label {
                    keyValue[keyName] = try value.jsonMap() //递归调用
                }else{
                   throw JSONMapError.emptyKey
                }
            }else{
                  throw JSONMapError.notConformProtocol
            }
        }
        return keyValue
    }
}

// 创建HJPerson并遵守CustomJSONMap协议
class HJPerson: CustomJSONMap{
    var age = 18
    var name = "寒冰射手"
    var height  = 1.85
}
// 需要遵守协议才能解析
extension Int: CustomJSONMap{}
extension String: CustomJSONMap{}


var p = HJPerson()
do{
    try p.jsonMap()
}catch {
    print("\(String(describing: (error as? LocalizedError)?.errorDescription))")
}

相关文章

网友评论

      本文标题:Swift异常处理(Error) — do try catch机

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