"无法覆盖已标记为不可用的'init'"可防止覆盖空init

Jon*_*han 6 ios swift swift2

我有一种情况,我试图覆盖,NSError以提供一个错误的实例,我将重新使用很多.

我的代码工作,直到我更新Xcode并转换为Swift 2.

public class NAUnexpectedResponseTypeError: NSError {
    public convenience init() {
        let messasge = "The object fetched by AFNetworking was not of an expected type."
        self.init(
            domain: "MyDomain",
            code: 6782,
            userInfo: [NSLocalizedDescriptionKey: messasge]
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

编译说Cannot override 'init' which has been marked unavailable.通过这样做,我能够破解它:

public class NAUnexpectedResponseTypeError: NSError {
    public class func error() -> NSError {
        let message = "The object fetched by AFNetworking was not of an expected type."
        return NAUnexpectedResponseTypeError(
            domain: "MyDomain",
            code: 6782,
            userInfo: [NSLocalizedDescriptionKey: message]
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:

  1. 有没有init办法在这样的情况下添加一个空方法?
  2. 如果是1,那么由于某种原因这是一个坏主意吗?
  3. 我使用类方法的解决方法是否是缓解此问题的适当方法?

编辑:

我提出了另一种解决方法,我更喜欢使用类方法的解决方法.我仍然不高兴我不能覆盖空init方法.

public class NAUnexpectedResponseTypeError: NSError {
    public convenience init(message: String?) {
        var errorMessage: String
        if let message = message {
            errorMessage = message
        } else {
            errorMessage = "The object fetched by AFNetworking was not of an expected type."
        }
        self.init(
            domain: "MyDomain",
            code: 6782,
            userInfo: [NSLocalizedDescriptionKey: errorMessage]
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 4

由于NSError它是不可变的,因此没有理由创建相同数据的多个实例。只需创建一个单一的常量实例:

let NAUnexpectedResponseTypeError = NSError(domain: "MyDomain",
    code: 6782,
    userInfo: [NSLocalizedDescriptionKey: "The object fetched by AFNetworking was not of an expected type."]
)
Run Code Online (Sandbox Code Playgroud)

如果您遇到的情况不是恒定的,那么扩展几乎总是比子类更好NSError。例如:

extension NSError {
    class func MyError(code code:code, message: String) -> NSError {
        return NSError(domain: "MyDomain", 
                       code: code,
                       userInfo: [NSLocalizedDescriptionKey: message])
   }
}
Run Code Online (Sandbox Code Playgroud)

这种扩展(作为一个类别)在 ObjC 中有着悠久的历史,并且是一个很好的模式,可以带到 Swift 中(如果你不能轻松使用enumErrorTypes,那么 Swift 就更好了)。

在许多情况下,我发现为此拥有一个顶级函数比扩展NSError. 例如:

private func makeError(code code:code, message: String) -> NSError {
    return NSError(domain: "MyDomain", 
                   code: code,
                   userInfo: [NSLocalizedDescriptionKey: message])
}
Run Code Online (Sandbox Code Playgroud)

(就我个人而言,当我必须使用 时,我总是在 Swift 中使用这些类型的函数NSError。在 ObjC 中,我通常在 上使用类别NSError。不知道为什么我改变了,但感觉更自然。)