【问题标题】:Swift Decode not working if setter & getter used如果使用了 setter 和 getter,则 Swift 解码不起作用
【发布时间】: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


【解决方案1】:

原来是私有实例变量(_row 和 _column)设置为 = 0 破坏了一切。

改变了它,一切正常。

发布这个答案以防其他人像我一样在两个晚上拉头发:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-08
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    相关资源
    最近更新 更多