在Swift中,如何为一个类创建一个便利的初始化,在该实现中初始化的实现创建类值而不是调用现有的初始化

Wal*_*GE1 5 swift

我觉得答案很明显,但是我无法弄清楚,这似乎是我经常遇到的问题。基本上我想做这样的事情:

extension NSData {
    convenience init(JSONObject: AnyObject) {
        do {
            self = try NSJSONSerialization.dataWithJSONObject(JSONObject, options: [])
        }
        catch {
            self = nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,它不能让我简单地为self赋值。我一直使用枚举来执行此操作,但不允许我使用类来执行此操作。在初始化器实现中,有什么方法可以使用初始化器实现中创建的类的实例来实现?

dfr*_*fri 4

说 Swift 中“尚不支持”工厂初始化器错误的它们的排除是一个设计决策,它们的使用旨在由可失败的初始化程序覆盖;引用以下 Apple Swift 博客文章

\n\n
\n

失败的初始化器消除了 Swift 中工厂方法的最常见原因,这是以前构造此对象时报告失败的唯一方法。

\n\n

...

\n\n

使用可失败初始化器可以更好地使用 Swift\xe2\x80\x99 的统一构造语法,从而消除初始化器和工厂方法之间的混乱和重复,从而简化了语言。

\n
\n\n

因此,就您而言,您可能正在寻找一种方便的可失败初始化程序。例如,沿着线的东西

\n\n
extension NSData {\n    convenience init?(JSONObject: AnyObject) {\n        do {\n            let foo = try NSJSONSerialization.dataWithJSONObject(JSONObject, options: [])\n            self.init(data: foo)\n        }\n        catch {\n            return nil\n        }\n    }\n}\n\n/* Example usage */\nlet foo : AnyObject = ["Foo":"bar"]\nlet bar = NSData.init(JSONObject: foo)\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

在问题的标题中包含“...而不是调用现有的 init”。当使用convenience初始化器时,必须在某个时刻调用指定的初始化器(同一类)(即使通过其他方便的初始化器)。来自Swift 语言指南 - 初始化 - 类继承和初始化

\n\n
\n

...

\n\n

规则2

\n\n

便利初始化程序必须调用同一类中的另一个初始化程序。\n

\n\n

规则3

\n\n

便利初始值设定项最终必须调用指定的初始值设定项。

\n
\n\n

然而,上面的示例代码允许便利初始化程序在NSJSONSerialization.dataWithJSONObject(...)失败时提前转义(失败),但如果成功,迟早需要调用指定的初始化程序(在本例中init(data:)是指定的初始化程序)。

\n\n
\n\n

有关可失败初始化程序的详细信息,请参阅Swift 语言指南 - 初始化 - 可失败初始化程序。有关初始化链 ( convenience -> ... -> designated initializer) 的附加说明,请参阅下面的 rickster:s 评论。

\n