最佳实践在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
    }
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...