给我们提出问题的当前实现如下:
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.
解决方法
在Swift 3中,编码方法对于每种类型都是重载的.我们有:
encode(Any?,forKey: String)
和
encode(Int,forKey: String)
编译器根据第一个参数的类型选择正确的方法(在Swift 2中,您有两个不同的方法名称,因此不需要类型信息).
你正在把Int!那里.由于Swift Evolution 0054,Swift 3中Implicitly Unwrapped Optionals的行为发生了变化.
如果您阅读了这些更改,您可以注意到将IUO转换为常规可选项比打开包装更受欢迎,因此转换为Any?比打包到Int更受欢迎.
However,the appearance of ! at the end of a property or variable declaration’s type no longer indicates that the declaration has IUO type; rather,it indicates that (1) the declaration has optional type,and (2) the declaration has an attribute indicating that its value may be implicitly forced. (No human would ever write or observe this attribute,but we will refer to it as @_autounwrapped.)
这个问题应该由
aCoder.encode(self.someVar!,forKey:"someVar")