所以我们一直在使用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")
}
}
Run Code Online (Sandbox Code Playgroud)
抛出以下错误:
*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeInt32ForKey:]: value for key (someVar) is not an integer number'
Run Code Online (Sandbox Code Playgroud)
有趣的是Swift 2.3的旧版实现没有任何问题:( self.someVar = decoder.decodeObject(forKey: "someVar") as! Int我从其他帖子中了解到这不起作用......)
那么我可能做错了什么?应该说原始值是从float中检索并转换为int.
此问题是由Swift 3中的多个更改引起的.
在Swift 3中,该encode方法对于每种类型都是重载的.我们有:
encode(Any?, forKey: String)
Run Code Online (Sandbox Code Playgroud)
和
encode(Int, forKey: String)
Run Code Online (Sandbox Code Playgroud)
编译器根据第一个参数的类型选择正确的方法(在Swift 2中,您有两个不同的方法名称,因此不需要类型信息).
你在Int!那里.由于Swift Evolution 0054,Swift 3中Implicitly Unwrapped Optionals的行为发生了变化.
如果您阅读了更改,您可以注意到,将IUO转换为常规可选项比首次打包更可取,因此转换Any?为优先于展开Int.
但是,外观!在属性或变量声明的类型末尾不再表示声明具有IUO类型; 相反,它表示(1)声明具有可选类型,(2)声明具有一个属性,指示可以隐式强制其值.(没有人会写或观察这个属性,但我们会将其称为@_autounwrapped.)
这个问题应该由
aCoder.encode(self.someVar!, forKey:"someVar")
Run Code Online (Sandbox Code Playgroud)
小智 5
首先检查您是否使用旧版本的swift编码数据,如果是这种情况您仍然需要使用
aDecoder.decodeObject(forKey: "someVar")
所以在这种情况下更完整的解决方案是
aDecoder.decodeObject(forKey: "age") as? Int ?? aDecoder.decodeInteger(forKey: "age")
Run Code Online (Sandbox Code Playgroud)
如果不是这种情况,请确保“someVar”实际上设置了一个值
| 归档时间: |
|
| 查看次数: |
1402 次 |
| 最近记录: |