最近两个晚上,我一直在努力解决一个问题,但是一无所获。
摘要问题如下:如果我在类中具有标准的公共属性,并对要存储在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)
}
}
在一个单独的类中,我存储具有上述类作为属性的“父”类“ Player”:
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 ='部分无法解码该对象,因此调用了Exception。
有趣的是,如果我使用代码的第1部分“保存”到coredata中,然后使用代码的第2部分“加载”数据,则一切正常。这让我认为问题在于编码(即使问题出现在解码点)。
很奇怪,如此小的更改导致它通过/失败,但是希望外面的某个人以前曾经历过这种反感。谢谢。
答案 0 :(得分:0)
事实证明,将私有实例变量(_row和_column)设置为= 0破坏了一切。
对此进行了更改,一切正常。
发布此答案,以防其他人像我一样拖了两个晚上:-)