【发布时间】:2018-11-30 18:06:36
【问题描述】:
在过去的几个晚上,我一直在努力解决一个问题,但没有成功。
摘要问题如下:如果我的类中有标准的公共属性并将数据编码然后存储在 Core Data 中,那么一切正常。如果我然后修改该类,使其具有明确定义的 getter 和 setter(使用私有变量),则编码似乎不起作用,因此从 Core Data 取回数据时解码失败。
这是我遇到问题的课程:
import Foundation
class MapLocation: NSObject, NSCoding {
// MARK: - Properties
// If section 1 below is used (and section 2 commented out) everything works fine. If section 2 below is used (and section 1 commented out) encode seems to fail for core data.
// Section 1 Start
public var row: Int!
public var column: Int!
// Section 1 End
// Section 2 Start
public var row: Int {
get {
return self._row
} set {
self._row = newValue
landType = MapLayout.landTypeForLocation(row: _row, column: _column)
}
}
public var column: Int {
get {
return self._column
} set {
self._column = newValue
landType = MapLayout.landTypeForLocation(row: _row, column: _column)
}
}
// MARK: - Instance variables
private var _row: Int = 0
private var _column: Int = 0
// Section 2 End
public var landType: LandType!
// MARK: - Constructors
override init() {
super.init()
// Game Starting location
self.row = 3
self.column = 4
self.landType = MapLayout.landTypeForLocation(row: self.row, column: self.column)
}
required init?(coder aDecoder: NSCoder) {
super.init()
guard let row = aDecoder.decodeObject(forKey: PropertyKey.playerLocationRow) as? Int,
let column = aDecoder.decodeObject(forKey: PropertyKey.playerLocationColumn) as? Int
else {
print("SVL Error: decoding failed MapLocation")
return nil
}
self.row = row
self.column = column
self.landType = MapLayout.landTypeForLocation(row: row, column: column)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(row, forKey: PropertyKey.playerLocationRow)
aCoder.encode(column, forKey: PropertyKey.playerLocationColumn)
}
}
在一个单独的类中,我存储具有上述类作为属性的“父”类“播放器”:
playerEntity.properties = try NSKeyedArchiver.archivedData(withRootObject: player, requiringSecureCoding: false) ...
然后使用以下命令从 Core Data 中检索保存的值:
if let returnPlayer = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(playerPropertiesData) as? Player {...
取消注释第 2 节时,我在控制台日志中得到以下信息: “SVL 错误:解码失败的 MapLocation” 这是因为解码器 init 方法的 'guard let row = ' 部分未能解码对象,因此调用了异常。
有趣的是,如果我使用代码的第 1 部分“保存”到 coredata 中,然后使用代码的第 2 部分“加载”数据,一切正常。这让我认为问题在于编码(即使问题出现在解码点)。
奇怪的是,如此微小的变化导致它通过/失败,但希望那里有人以前经历过这种异常。谢谢。
【问题讨论】:
-
不相关但在 Swift 中没有支持的实例变量。删除以下划线开头的私有变量并使用
didSet观察者。
标签: swift serialization core-data decode encode