如果使用setter和getter,则快速解码不起作用

时间:2018-11-30 18:06:36

标签: swift serialization core-data decode encode

最近两个晚上,我一直在努力解决一个问题,但是一无所获。

摘要问题如下:如果我在类中具有标准的公共属性,并对要存储在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部分“加载”数据,则一切正常。这让我认为问题在于编码(即使问题出现在解码点)。

很奇怪,如此小的更改导致它通过/失败,但是希望外面的某个人以前曾经历过这种反感。谢谢。

1 个答案:

答案 0 :(得分:0)

事实证明,将私有实例变量(_row和_column)设置为= 0破坏了一切。

对此进行了更改,一切正常。

发布此答案,以防其他人像我一样拖了两个晚上:-)

相关问题