Swift:使用Failable Initializer从JSON创建模型类

时间:2015-12-09 20:59:54

标签: swift initialization

我正在尝试实现一些可以使用JSON数据[String : AnyObject]初始化的类。可用的初始值设定项似乎非常适合这种用例,但我似乎无法正确获取语法(不会创建丑陋的代码)。

是否可以做这样的事情?:

class Person {
  let firstName: String
  let middleName: String?

  init?(JSONData data: [String : AnyObject]) {
    do {
      try {
        self.firstName = data["firstName"] as! String
        self.middleName = data["middleName"] as? String
      }
    } catch {
      return nil
    }
  }
}

1 个答案:

答案 0 :(得分:5)

这就是我通常使用可用的初始化程序定义模型类型的方法。

struct Person {
    let firstName: String
    let middleName: String?

    init?(JSONData data:[String:AnyObject]) {
        guard let firstName = data["firstName"] as? String else { return nil }
        self.firstName = firstName
        self.middleName = data["middleName"] as? String
    }
}

为什么是结构?

正如您所看到的,我使用的是Struct而不是Class,至少有两个重要原因:

  • failable initializers可以更好地使用结构,因为您可以在未初始化所有存储属性的情况下返回nil
  • 他们更快(因为保存在堆栈而不是堆中)

为什么要守护?

我也更喜欢使用guard let构造,因为它表明如果没有检索到某些强制值,那么初始化必须失败。

更多

我的初始化程序版本不需要middleName。我决定这样做是因为你将middleName定义为可选项。但是,如果您想强制middleName,只需更改Person,如下所示

struct Person {
    let firstName: String
    let middleName: String

    init?(JSONData data:[String:AnyObject]) {
        guard let
            firstName = data["firstName"] as? String,
            middleName = data["middleName"] as? String else { return nil }
        self.firstName = firstName
        self.middleName = middleName
    }
}

等等,结构是值类型!每个副本我都会浪费大量内存?

都能跟得上!

  

[...] Swift只在幕后执行实际复制   绝对有必要这样做。 Swift管理所有值复制到   确保最佳性能,您不应该避免分配尝试   优先于此优化。

     

The Swift Programming Language