在下面的代码中,我试图定义一个简单的模型类及其可失败的初始值设定项,它将(json-)字典作为参数.如果原始json中未定义用户名,则初始值设定项应返回nil.

1.

在从初始值设定项返回nil之前,必须初始化类实例的所有存储属性.

这没有道理.当我计划返回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人中的Update:人(2016年3月21日发布):

在对象完全初始化之前,声明为failable或throwing的指定类初始值设定项现在可以分别返回nil或throwing错误.


For Swift 2.1 and earlier:

根据苹果的文档(以及你的编译器错误),在从一个失败的初始化器返回nil之前,类必须初始化它存储的所有属性:

然而,对于类,一个失败的初始值设定项可以触发

100 It actually works fine for structures and enumerations, just not classes.

处理在初始值设定项失败之前无法初始化的存储属性的建议方法是将它们声明为隐式展开选项.

Example from the docs:

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

在上面的示例中,Product类的name属性是

然而,在您的例子中,简单地将userName定义为String!并不能修复编译错误,因为您仍然需要担心初始化基类NSObject上的属性.幸运的是,将userName定义为String!,实际上可以在return 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相关问答推荐

如何在HStack中均匀分布视图?

通常从数组调用的SWIFT静态协议函数

如何使用Duration.TimeFormatStyle以h m s格式快速格式化时间

为什么 Swift URL 的 init?(string: String,relativeTo: URL?) 仅添加协议?

如何使用模型在 SwiftUI 的列表中进行搜索

我如何在 swift 中的 viewdidload 之前进行委托?

如何在设备(或常量)地址空间中创建缓冲区?

OSX 中的 Popover 无法确定透明度

在SwiftUI中使用ForEach循环来显示字典项的键和值在Form视图中

如何从我的 macOS 应用程序打开 (.log) 文件?

如何修改下面的代码,使图像 Select 的顺序与使用快速并发的图像呈现的顺序相匹配?

这是 Int64 Swift Decoding 多余的吗?

创建 ViewModel 时 iOS 模拟器上的黑屏

符合协议 - 错误?

如何以快速 Select 器菜单样式调整图像大小

Swift 读写图片占用大量内存

是 swift 中另一个日期的同一周、月、年的日期

为 UIImagePicker 设置委托返回错误

如何使用 swift 在 tableview 中填充两个不同数组的两个部分?

ld:入口点(_main)未定义.对于架构 x86_64:Xcode 9