使用 SwiftyJSON 的 Swift 可失败初始化器

Posted

技术标签:

【中文标题】使用 SwiftyJSON 的 Swift 可失败初始化器【英文标题】:Swift Failable Initializer with SwiftyJSON 【发布时间】:2016-02-09 13:43:14 【问题描述】:

我正在尝试使用来自SwiftyJSON 的一些 JSON 初始化一个简单的数据模型对象。如果任何所需的 JSON 值不存在,我希望初始化程序失败并返回 nil。这是我的代码:

class ProductCategory: NSObject 

  let id: String
  let sortOrder: Int
  let name: String
  let imageURL: String
  let ranges: [String]

  init?(json: JSON) 
    if let jsonID = json["id"].string,
       jsonSortOrder = json["sortOrder"].int,
       jsonName = json["name"].string,
       jsonImageURL = json["imageURL"].string 
      id = jsonID
      sortOrder = jsonSortOrder
      name = jsonName
      imageURL = jsonImageURL
      ranges = json["ranges"].arrayValue.map  $0.string! 
     else 
      return nil
    
  

我希望这能奏效。如果我们没有达到所有这些 json 值,只需返回 nil 并退出。但是,我在return nil 上收到错误消息,说明:

类实例的所有存储属性必须在之前初始化 从初始化器返回 nil。

我很困惑:如果出现问题,我可以在不设置它的情况下退出可失败的初始化程序吗?返回的对象会是nil,为什么设置它的属性会有任何价值?

【问题讨论】:

我刚刚将您的代码粘贴到 Playground 中,没有任何错误 - 您也不应该有任何错误。是否有任何其他代码可能与此冲突? 奇怪。不,这是课程的全部内容。 也许只是 Xcode 吓坏了。您是否尝试过菜单“产品”中的“清洁”?或者任何其他已知的重置 Xcode 状态的技术,比如清理“派生数据”? 是的,都清理干净了。这是一个长期存在的问题,看来! 所以,问题出在从 NSObject 继承。如果我不这样做,一切都很好。 【参考方案1】:

所以这就是我最终所做的——Greg 是对的,但结果我最终切换到了 struct

struct ProductCategory 

    let id: String
    let sortOrder: Int
    let name: String
    let imageURL: String
    let ranges: [String]

    init?(json: JSON) 
        guard let jsonID = json["id"].string,
              let jsonSortOrder = json["sortOrder"].int,
              let jsonName = json["name"].string,
              let jsonImageURL = json["image"].string else 
            return nil
        

        self.id = jsonID
        self.sortOrder = jsonSortOrder
        self.name = jsonName
        self.imageURL = jsonImageURL
        self.ranges = json["ranges"].arrayValue.map  $0.string! 
    


【讨论】:

【参考方案2】:

Failable Initializers for Classes:

“然而,对于类来说,只有在该类引入的所有存储属性都已设置为初始值并且任何初始化器委托已经发生后,可失败的初始化器才能触发初始化失败。”

所以

init?(json: JSON) 
    self.id = json["id"].string
    self.sortOrder = json["sortOrder"].int
    ...
    if ...  return nil 

【讨论】:

所以,问题出在从 NSObject 继承。如果我不这样做,一切都很好。

以上是关于使用 SwiftyJSON 的 Swift 可失败初始化器的主要内容,如果未能解决你的问题,请参考以下文章

Swift 2 + SwiftyJSON:使用未解决的标识符错误

swift、Alamofire、SwiftyJSON:如何解析 arrayObject

“当前 SwiftyJSON(通过 Swift 3.0.2)无法使用 Swift 3.1 导入”的原因是啥

SwiftyJSON 问题 Swift 2

Swift 使用 Alamofire 和 SwiftyJSON 解析 Json [关闭]

使用 swiftyjson 和 swift 解析嵌入的 json