Последние пару вечеров я пытался проработать проблему, но ничего не получилось.
Сводная проблема заключается в следующем: если у меня есть стандартные общедоступные свойства в моем классе и я кодирую данные для последующего хранения в 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кода для «загрузки» данных, все работает отлично.Это заставляет меня думать, что проблема заключается в кодировании (даже если проблема появляется в точке декодирования).
Это так странно, что такое незначительное изменение приводит к тому, что оно проходит / терпит неудачу, но надеется, что кто-то там естьиспытал эту аномалию раньше.Благодаря.