最佳实践在swift中实现failable初始化

使用以下代码,我尝试定义一个简单的模型类,它的failable初始化,它接受一个(json-)字典作为参数。如果用户名未在原始json中定义,初始化程序应返回nil。

1。
为什么代码不编译?错误消息说:

"All stored properties of a class instance must be initialized before returning nil from an initializer"

这没有意义。当我计划返回nil时,为什么要初始化这些属性

2。
我的方法是正确的,还是会有其他想法或共同模式来实现我的目标?

class User: NSObject {

    let userName: String
    let isSuperUser: Bool = false
    let someDetails: [String]?

    init?(dictionary: NSDictionary) {


        if let value: String = dictionary["user_name"] as? String {
            userName = value
        }
        else {
           return nil
        }

        if let value: Bool = dictionary["super_user"] as? Bool {
            isSuperUser = value
        }

        someDetails = dictionary["some_details"] as? Array

        super.init()
    }
}
更新:从 Swift 2.2 Change Log(发布2016年3月21日):

Designated class initializers declared as failable or throwing may now return nil or throw an error,respectively,before the object has been fully initialized.

对于Swift 2.1及更早版本:

根据苹果的文档(和你的编译器错误),类必须初始化所有存储的属性,然后从failable初始化器返回nil:

For classes,however,a failable initializer can trigger an
initialization failure only after all stored properties introduced by
that class have been set to an initial value and any initializer
delegation has taken place.

注意:它实际上适用于结构和枚举,只是不是类。

建议的处理在初始化器失败之前无法初始化的存储属性方法是将它们声明为隐式解包的可选项。

文档中的示例:

class Product {
    let name: String!
    init?(name: String) {
        if name.isEmpty { return nil }
        self.name = name
    }
}

In the example above,the name property of the Product class is
defined as having an implicitly unwrapped optional string type
(String!). Because it is of an optional type,this means that the name
property has a default value of nil before it is assigned a specific
value during initialization. This default value of nil in turn means
that all of the properties introduced by the Product class have a
valid initial value. As a result,the failable initializer for Product
can trigger an initialization failure at the start of the initializer
if it is passed an empty string,before assigning a specific value to
the name property within the initializer.

在你的情况下,然而,简单地定义userName作为一个字符串!不修复编译错误,因为你仍然需要担心初始化基类NSObject的属性。幸运的是,使用userName定义为String!,你可以在返回nil之前调用super.init(),它将初始化你的NSObject基类并修复编译错误

class User: NSObject {

    let userName: String!
    let isSuperUser: Bool = false
    let someDetails: [String]?

    init?(dictionary: NSDictionary) {
        super.init()

        if let value = dictionary["user_name"] as? String {
            self.userName = value
        }
        else {
            return nil
        }

        if let value: Bool = dictionary["super_user"] as? Bool {
            self.isSuperUser = value
        }

        self.someDetails = dictionary["some_details"] as? Array
    }
}

相关文章

Swift 正式开源!Swift 团队很高兴宣布 Swift 开始开源新篇章。自从苹果发布 Swfit 编程语言,就成为了...
快,快,快!动动您的小手,分享给更多朋友! 苹果去年推出了全新的编程语言Swift,试图让iOS开发更简单...
开发者(KaiFaX) 面向开发者、程序员的专业平台! 和今年年初承诺的一样,苹果贴出了Swift语言的源码,...
本文由@Chun发表于Chun Tips :http://chun.tips/blog/2014/12/11/shi-yong-swift-gou-jian-zi-ding-yi...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...