代码之家  ›  专栏  ›  技术社区  ›  Riccardo Perego

Swift设置值为空可选产量失败

  •  0
  • Riccardo Perego  · 技术社区  · 6 年前

    我有一个叫做 DataManager 这就是它的样子:

    class DataManager: NSObject, NSCoding {
    
        var money: Double = 0
        var netWorth: Double = 0
        var businessNum: Int = 0
        var generalEPM: Int = 0
        var generalThreat: Int = 0
    
    
        override init() {
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            self.money = (aDecoder.decodeDouble(forKey: "DMMoney"))
            self.netWorth = (aDecoder.decodeDouble(forKey: "DMNetWorth"))
            self.businessNum = (aDecoder.decodeInteger(forKey: "DMBusinessNum"))
            self.generalEPM = (aDecoder.decodeInteger(forKey: "DMGeneralEPM"))
            self.generalThreat = (aDecoder.decodeInteger(forKey: "DMGeneralThreat"))
        }
    
        func encode(with aCoder: NSCoder) {
            aCoder.encode(self.money, forKey: "DMMoney")
            aCoder.encode(self.netWorth, forKey: "DMNetWorth")
            aCoder.encode(self.businessNum, forKey: "DMBusinessNum")
            aCoder.encode(self.generalEPM, forKey: "DMGeneralEPM")
            aCoder.encode(self.generalThreat, forKey: "DMGeneralThreat")
        }
    
    }
    

    然后,我创建该类的可选实例,因为它可以为空(一旦用户第一次打开应用程序):

    var appData:DataManager?
    

    然后,我有两个功能来保存和加载数据:

    func saveData() {
        appData?.transformNetWorth()
        appData?.updateAllVariables()
        let encodeData: Data = NSKeyedArchiver.archivedData(withRootObject: appData)
        userDefaults.set(encodeData, forKey: "appData")
        userDefaults.synchronize()
    }
    
    func loadData() {
    
        if let x = userDefaults.object(forKey: "appData") as? Data {
            appData = NSKeyedUnarchiver.unarchiveObject(with: x) as? DataManager
        }
    }
    

    数据管理器 为空,如果为空,则为其提供以下值:

    if appData == nil {
        appData?.money = 100
        appData?.businessNum = 0
        appData?.generalThreat = 0
        appData?.generalEPM = 0
        appData?.netWorth = 0
        saveData()
    }
    

    不过,在发生这种情况并调用saveData()函数后,我会尝试使用appData!。钱,但应用程序崩溃了,它告诉我:“在打开包装时意外发现零…”,虽然我给所有的类参数赋值。请帮忙,因为我不知道错误在哪里。谢谢

    (当然,在尝试访问数据之前会调用loadData())

    1 回复  |  直到 6 年前
        1
  •  0
  •   rmaddy    6 年前

    appData nil . 你从不给它赋值。

    您想要的是:

    if appData == nil {
        appData = DataManager()
        appData?.money = 100
        // and the rest
    }
    

    这解决了眼前的问题,但您确实需要重构所有代码,以便更干净地使用optionals。

    例如,更新 saveData

    func saveData() {
        if let appData = appData {
            appData.transformNetWorth()
            appData.updateAllVariables()
            let encodeData: Data = NSKeyedArchiver.archivedData(withRootObject: appData)
            userDefaults.set(encodeData, forKey: "appData")
        }
    }
    

    这避免了所有不必要的 ? 它可以确保在以下情况下不会运行所有代码 应用程序数据 .