Как декодировать Double с помощью NSCoder, NSObject и Swift 3 для iOS

Я пытаюсь сохранить и загрузить объект из постоянного хранилища в Xcode 8.0 с помощью Swift.

Я следил за Начало разработки приложений для iOS (Swift): прямо сейчас учебник от Apple, и у него была такая же проблема с целочисленным значением звездного рейтинга.

Это «обрезанная» версия моего класса «Расходы», чтобы показать переменную «сумма», с которой у меня возникли проблемы:

class Expense: NSObject, NSCoding {
    var amount: Double

    static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
    static let ArchiveURL = DocumentsDirectory.appendingPathComponent("expenses")

    struct PropertyKey {
        static let amountKey = "amount"
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(amount, forKey:PropertyKey.amountKey)
    }

    required convenience init?(coder aDecoder: NSCoder) {
        let amount = aDecoder.decodeObject(forKey: PropertyKey.amountKey) as! Double        

        self.init(date: date, amount: amount, description: description, image: image)
    }
}

Когда я запускаю симулятор, и он пытается загрузить «сумму», я получаю следующее исключение: «фатальная ошибка: неожиданно найден ноль при развертывании необязательного значения». Я очень новичок в Swift и xCode, и я действительно не знаю, как это исправить.


person Frederik    schedule 06.10.2016    source источник
comment
пусть сумма = aDecoder.decodeDouble (forKey: PropertyKey.amountKey) как Double? в целях безопасности не забудьте указать сумму как необязательную (добавляя двойную?) Swift 3   -  person Ahmad F    schedule 06.10.2016
comment
где заканчивается метод required convenience init?(coder aDecoder: NSCoder) {?   -  person Bista    schedule 06.10.2016
comment
@ Ахмад, спасибо, это сработало. Можете ли вы опубликовать свой комментарий в качестве ответа, чтобы я мог принять его :)   -  person Frederik    schedule 06.10.2016
comment
@FrederikNorlykEriksen рад помочь :) по вашему запросу я разместил это как ответ   -  person Ahmad F    schedule 06.10.2016


Ответы (2)


Попробуйте загрузить свойство как необязательное:

let amount = aDecoder.decodeObject(forKey: PropertyKey.amountKey) as Double?

Кроме того, чтобы получить свойство из хранилища, вы должны сначала сохранить его. Если он еще не сохранен, вам следует обработать случай, когда он nil.

person Max Pevsner    schedule 06.10.2016

person    schedule
comment
Не нужно говорить as Double? — просто пусть amount не является необязательным и позволяет ему повышаться каждый раз, когда его нужно передать в необязательный параметр. Высказывание as Double? не добавляет никакой безопасности. - person Hamish; 24.11.2016