• swift3.0之后的Error处理


    在之前的版本中,Swift中Error与OC中NSError没有关系。但是现在两者可以互相强转。

    我们看看两者的区别:Error是一个实现Error协议的枚举或者结构体,对外能够获取的具体信息只有rawValue。但是我们知道NSError是有UserInfo和domain的。

    先来看看Swift中Error

    枚举Error:

    enum LoginError: Error {
        case LoginSucess
        case LoginPasswordWrong
        case LoginMobileInvalid
    }

    基本的error处理:

    //注意catch中的error是抛出的Error对象,这个对象没有通过var error:Error创建,在catch的大括号里直接就能拿到,如果想要取得错误信息,直接处理error就可以
      // 模拟登录接口
        func loginMethod(nick: String,password: String) throws {
            guard !nick.isEmpty else {
                throw LoginError.LoginMobileInvalid
            }
            guard !password.isEmpty else {
                throw LoginError.LoginPasswordWrong
            }
            print("登录成功")
        }
    // 购物接口,购物之前要先登录 func pay() throws { do { try loginMethod(nick: "", password: "wangdachui") } catch LoginError.LoginMobileInvalid { print("昵称为空") } catch LoginError.LoginPasswordWrong { print("密码错误") } catch { print("登录成功") }
     
        }

    结构体Error:

    struct XMLParsingError: Error {
     enum ErrorKind {
         case invalidCharacter
         case mismatchedTag
         case internalError
     }
    
     let line: Int
     let column: Int
     let kind: ErrorKind
    }

    结构体Error的基本处理:

     func parse(_ source: String) throws -> XMLDoc {
         // ...
         throw XMLParsingError(line: 19, column: 5, kind: .mismatchedTag)
         // ...
     }
    
    function:
    
     do {
         let xmlDoc = try parse(myXMLData)
     } catch let e as XMLParsingError {
         print("Parsing error: (e.kind) [(e.line):(e.column)]")
     } catch {
         print("Other error: (error)")
     }
     // Prints "Parsing error: mismatchedTag [19:5]"

    但是我们知道NSError是有UserInfo和domain的:

    throw NSError(code: HomeworkError.dogAteIt.rawValue,
                  domain: HomeworkError._domain,
                  userInfo: [ NSLocalizedDescriptionKey : "the dog ate it" ])

    如果OC中的NSError桥接到Swift中,变成Error类型,那么获取NSError中的UserInfo信息也变成了一件头疼的事情,比如AVError:

    catch let error as NSError where error._domain == AVFoundationErrorDomain 
    && error._code == AVFoundationErrorDomain.diskFull.rawValue {
      // okay: userInfo is finally accessible, but still weakly typed
    }

    很显然,解决方式就是提供一个方式可以让这两个类型可以无损的转换。

    LocalizedError

    增加了一个LocalizedError协议。这个协议增加了errorDescription属性。如果Error同时实现这个协议,相比原来只有rawValue就增加了更多的信息。

    extension HomeworkError : LocalizedError {
      var errorDescription: String? {
        switch self {
        case .forgotten: return NSLocalizedString("I forgot it")
        case .lost: return NSLocalizedString("I lost it")
        case .dogAteIt: return NSLocalizedString("The dog ate it")
        }
      }
    }

    这个协议同时还有三个属性:failureReason、helpAnchor、recoverySuggestion。

    在NSError中也有对应的三个属性:

    @property (readonly, copy) NSString *localizedDescription;
    
    @property (nullable, readonly, copy) NSString *localizedFailureReason;
    
    @property (nullable, readonly, copy) NSString *localizedRecoverySuggestion;

    CustomNSError

    CustomNSError 用来桥接原来NSError中的code、domain、UserInfo。

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

    如果想让我们的自定义Error可以转成NSError,实现CustomNSError就可以完整的as成NSError。

    RecoverableError

    这次还给Error增加了RecoverableError协议。用来提示用户可以通过什么样的方式来处理这个Error。


    参考资料:http://www.jianshu.com/p/a36047852ccc

    参考资料:http://www.jianshu.com/p/911c7a2805d5

  • 相关阅读:
    理解volatile与synchronized
    实现任意两个数的互换
    增删改查+部分前段内容
    Hibernate知识点小结汇总
    Spring知识点小结(一)
    JDBC相关
    Redis工具之Jedis
    Hibernate知识点小结(四)--JPA
    Hibernate知识点小结(三)-->一对多与多对多配置
    Hibernate知识点小结(二)
  • 原文地址:https://www.cnblogs.com/6duxz/p/7424463.html
Copyright © 2020-2023  润新知