【问题标题】:How do I get an optional from decodeIntegerForKey instead of 0?如何从 decodeIntegerForKey 而不是 0 获得可选值?
【发布时间】:2015-09-09 23:11:53
【问题描述】:

我的应用通过归档具有属性的类的实例,将设置保存到 iOS 设备上的文件中。该类使用 NSCoding 协议,因此,我使用 encodeWithCoder 对这些属性进行编码。然后我尝试使用诸如tempInt = decoder.decodeIntegerForKey("profileFlags") as Int之类的命令将这些文件读回内存中

到目前为止,这运行良好,但现在我需要能够存储其他属性并检索它们。本质上,这个归档对象的结构正在改变,但用户已经拥有旧结构的文件(具有更少的属性)。如果用户有一个具有新结构(附加属性)的文件,那么我想阅读它们。如果没有,我希望能够执行代码来处理它并提供默认值。

我尝试使用不存在的键 tempInt = decoder.decodeIntegerForKey("nonExistentKey") as Int,希望得到一个 nil 值,但它返回一个零。不幸的是,这是我真正需要一个可选值的地方,因为 0 是一个有效值。

我能找到的最接近的帮助文章是Swift: decodeObjectForKey crashes if key doesn't exist,但这似乎不适用于这里。似乎 decodeObjectForKey 返回一个可选值,而 decodeIntegerForKey 返回一个 Integer。

关于如何做到这一点的任何想法?

【问题讨论】:

    标签: ios swift nscoding


    【解决方案1】:

    您可以使用decoder.containsValueForKey("nonExistentKey") 检查是否存在实际值,并且仅当使用decodeIntegerForKey 提取它时:

    if decoder.containsValueForKey("nonExistentKey") {
        let tempInt = decoder.decodeIntegerForKey("nonExistentKey") 
    }
    

    【讨论】:

    • “如果编码的整数不适合默认整数大小,则该方法会引发 NSRangeException。”不幸的是,在 Swift 中很难处理。
    【解决方案2】:

    您可以使用返回零而不是零的decodeObjectForKey。你只需要向下转换为 Int 如下:

    decoder.decodeObjectForKey("profileFlags") as? Int
    

    【讨论】:

      【解决方案3】:

      @luk2302 给了你答案,但我想稍微调整一下语法并扩展它:

      var tempInt: Int? 
      let key = "profileFlags"
      let hasValue = decoder.containsValueForKey(key)
      tempInt = hasValue ? decoder.decodeIntegerForKey(key) : nil
      

      最后一条语句是使用“三级运算符”,效果与:

      if hasValue
      {
        tempInt = decoder.decodeIntegerForKey(key)
      }
      else
      {
        tempInt = nil
      }
      

      ...但都在 1 行中。在你习惯之前它看起来有点奇怪,但它是表达这种事情的一种非常简洁的方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 2017-03-25
        相关资源
        最近更新 更多