在Swift中实现可失败的初始化程序的最佳实践

在Swift中实现可失败的初始化程序的最佳实践

本文介绍了在Swift中实现可失败的初始化程序的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码,我尝试定义一个简单的模型类,它是可失败的初始化程序,它将(json-)字典作为参数.如果原始json中未定义用户名,则初始化程序应返回nil.

With the following code I try to define a simple model class and it's failable initializer, which takes a (json-) dictionary as parameter. The initializer should return nil if the user name is not defined in the original json.

1.代码为什么不编译?错误消息显示:

1.Why doesn't the code compile? The error message says:

那没有道理.计划返回nil时为什么要初始化那些属性?

That doesn't make sense. Why should I initialize those properties when I plan to return nil?

2.是我的方法正确,还是有其他想法或通用模式可以实现我的目标?

2.Is my approach the right one or would there be other ideas or common patterns to achieve my goal?

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更改日志(2016年3月21日发布):

Update: From the Swift 2.2 Change Log (released March 21, 2016):


对于Swift 2.1和更低版本:

根据Apple的文档(以及您的编译器错误),类必须从失败的初始化程序返回nil之前,初始化其所有存储的属性:

According to Apple's documentation (and your compiler error), a class must initialize all its stored properties before returning nil from a failable initializer:

注意:实际上,它对结构和枚举有效,但对类却无效.

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

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

The suggested way to handle stored properties that can't be initialized before the initializer fails is to declare them as implicitly unwrapped optionals.

文档示例:

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

但是,对于您而言,仅将userName定义为String!并不能解决编译错误,因为您仍然需要担心初始化基类NSObject上的属性.幸运的是,将userName定义为String!,您实际上可以在return nil之前调用super.init(),这将初始化您的NSObject基类并修复编译错误.

In your case, however, simply defining userName as a String! does not fix the compile error because you still need to worry about initializing the properties on your base class, NSObject. Luckily, with userName defined as a String!, you can actually call super.init() before you return nil which will init your NSObject base class and fix the compile error.

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中实现可失败的初始化程序的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 15:29