【问题标题】:"Cannot override 'init' which has been marked unavailable" prevents overriding empty init“无法覆盖已标记为不可用的'init'”可防止覆盖空的init
【发布时间】:2015-09-23 20:48:50
【问题描述】:

我有一种情况,我试图覆盖 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]
        )
    }
}

编译器显示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]
        )
    }
}

所以,我的问题是:

  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]
        )
    }
}

【问题讨论】:

  • 除了此处显示的内容之外,您是否还向您的课程添加了更多代码?因为我想知道为什么子类是必要的。
  • @TomHarrington 你会建议类似 NSError 的扩展吗?

标签: ios swift swift2


【解决方案1】:

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

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

如果您的情况不是固定不变的,那么扩展而不是子类NSError 几乎总是更好。例如:

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

这种扩展(作为一个类别)在 ObjC 中有很长的历史,是一个很好的模式可以引入 Swift(如果你不能轻易使用 enumErrorTypes,它是更好的 Swift)。

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

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

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

【讨论】:

  • 非常有帮助和彻底。非常感谢!
【解决方案2】:

你不能覆盖空的初始化,它被标记为不可用,所以你不能用它做任何事情。

您确实有另一种解决方法

public class NAUnexpectedResponseTypeError: NSError {

    public convenience init(message: String = "The object fetched by AFNetworking was not of an expected type.") {
            self.init(
                domain: "MyDomain",
                code: 6782,
                userInfo: [NSLocalizedDescriptionKey: message]
        )
    }
}

我没有测试它,但它应该可以工作。

既然您使用的是 swift 2.0,为什么不让您的实例符合错误类型而不是继承 NSError 呢?它会更干净,更惯用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 2018-11-18
    • 2019-07-14
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多