Быстрое декодирование не работает, если используются сеттер и геттер - PullRequest
0 голосов
/ 30 ноября 2018

Последние пару вечеров я пытался проработать проблему, но ничего не получилось.

Сводная проблема заключается в следующем: если у меня есть стандартные общедоступные свойства в моем классе и я кодирую данные для последующего хранения в 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) ...

И затем получить сохраненные значения из Базовых данных, используя:

   if let returnPlayer = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(playerPropertiesData) as? Player {...

Когда раздел 2 не закомментирован, я получаю в журнале консоли следующее: «Ошибка SVL: декодирование не удалось MapLocation» Это происходит потому, чтоСекция 'guard let row =' в методе init декодера не может декодировать объект и вызывает исключение.

Интересно, если я использую секцию 1 кода для «сохранения» в coredata, а затем использую секцию 2кода для «загрузки» данных, все работает отлично.Это заставляет меня думать, что проблема заключается в кодировании (даже если проблема появляется в точке декодирования).

Это так странно, что такое незначительное изменение приводит к тому, что оно проходит / терпит неудачу, но надеется, что кто-то там естьиспытал эту аномалию раньше.Благодаря.

1 Ответ

0 голосов
/ 30 ноября 2018

Оказалось, что установка личных переменных экземпляра (_row и _column) в = 0 разрушает все.

Это изменилось, и все заработало правильно.

Публикация этогоответь, если кто-нибудь еще 2 вечера тянет свои волосы, как я :-)

...