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

时间:2018-02-22 17:04:48

标签: swift crash optional

我有一个名为import os file_dict = {'abc.mp3': 10, 'abc.jpg': 20, 'abc.mp4': 30, 'xyz.mp3': 40, 'mno.mp3': 40, 'xyz.jpg': 30} added_dict = {} for k, v in file_dict.items(): ext = os.path.splitext(k)[-1][1:] added_dict[ext] = added_dict.setdefault(ext, 0) + v print(added_dict) 的数据类,它的外观如下:

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")
    }

}

然后我有2个函数来保存和加载数据:

var appData:DataManager?

在我的AppDelegate中,一旦应用程序运行,它会检查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 } } 是否为空,如果是,则为其提供以下值:

DataManager

然而,在发生这种情况之后并且在调用saveData()函数之后,我尝试使用appData!.money,但应用程序崩溃告诉我:"在展开时出乎意料地发现nil ...",虽然我给所有类参数赋值。请帮忙,因为我不知道错误在哪里。谢谢!

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

1 个答案:

答案 0 :(得分:0)

appDatanil。你永远不会给它赋值。

你想要这样的东西:

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

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

例如,将您的saveData更新为:

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

这可以避免所有不必要的?使用,并确保在appDatanil时您不会运行所有代码。