为什么我的Swift 3.0解码器decodeInteger不能用于整数?

时间:2016-10-12 13:24:52

标签: ios swift3

所以我们一直在使用Groups来保存和检索扩展程序和主应用程序中的一些数据,一切都适用于Swift 2.3但我们更新到Swift 3.0并遇到了一些问题。

给我们带来问题的当前实现如下:

open class SomeClass: NSObject, NSCoding {
  open var someVar: Int!

  open func encode(with aCoder: NSCoder) {
    aCoder.encode(self.someVar, forKey:"someVar")
  }

  public required convenience init?(coder decoder: NSCoder) {
    // this is where it breaks
    self.someVar = decoder.decodeInteger(forKey: "someVar") 
  }

}

抛出以下错误:

*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeInt32ForKey:]: value for key (someVar) is not an integer number'

有趣的是,Swift 2.3的旧版实现没有任何问题:self.someVar = decoder.decodeObject(forKey: "someVar") as! Int(我从其他帖子中了解到这不起作用......)

那么我可能做错了什么?应该说原始值是从float中检索并转换为int。

2 个答案:

答案 0 :(得分:9)

此问题是由Swift 3中的多个更改引起的。

在Swift 3中,每种类型的encode方法都会重载。我们有:

encode(Any?, forKey: String)

encode(Int, forKey: String)

编译器根据第一个参数的类型选择正确的方法(在Swift 2中,您有两个不同的方法名称,因此不需要类型信息)。

你将Int!放在那里。由于Swift Evolution 0054,Swift 3中Implicitly Unwrapped Optionals的行为发生了变化。

如果您阅读了更改,则可以注意到,将IUO转换为常规可选项比首次展开更受欢迎,因此优先转换为Any?而不是展开到Int

  但是,外观!在属性或变量声明类型的末尾不再表示声明具有IUO类型;相反,它表示(1)声明具有可选类型,(2)声明具有一个属性,指示可以隐式强制其值。 (没有人会写或观察这个属性,但我们会将其称为@_autounwrapped。)

问题应该由

解决
aCoder.encode(self.someVar!, forKey:"someVar")

答案 1 :(得分:4)

首先检查您是否使用旧版本的swift编码数据,如果是这种情况,您仍然需要使用     aDecoder.decodeObject(forKey: "someVar")

因此,在这种情况下,更完整的解决方案将是

aDecoder.decodeObject(forKey: "age") as? Int ?? aDecoder.decodeInteger(forKey: "age")

如果情况并非如此,那么请确保" someVar"实际上有一个值集