Swift中点击按钮存储Label文本到UserDefaults却返回nil的问题求助
解决UserDefaults存数组返回nil的问题
嘿,我一眼就看到问题所在啦!你这段代码的核心问题是第一次点击按钮时,UserDefaults里还没有"cartt"这个键,导致你拿到的maAr是nil,后续的append操作根本没执行,最后存进去的还是nil,所以打印出来自然是nil。
给你修正后的代码,我还加了一些更严谨的处理:
@IBAction func tapAddBtn(_ sender: UIButton) { let def = UserDefaults.standard // 关键改进:如果原来的数组不存在,就初始化一个空数组,避免nil var maAr = def.array(forKey: "cartt") as? [[String: Any]] ?? [] // 先确保所有Label的文本都不为空,避免存入nil值 guard let name = nameLbl.text, let price = costLbl.text, let qty = quantNumberLabel.text else { print("某个Label的文本为空,无法添加到购物车") return } // 现在可以安全地添加数据了 maAr.append(["name": name, "price": price, "qty": qty]) def.set(maAr, forKey: "cartt") // iOS 10+ 不需要手动调用synchronize(),系统会自动同步 // def.synchronize() print(def.object(forKey: "cartt") ?? "购物车数组为空") }
再给你拆解一下为什么原来的代码会出问题:
- 首次运行时,
UserDefaults.standard.array(forKey: "cartt")返回nil,maAr就变成了nil。可选链maAr?.append会直接跳过,不会执行添加操作,所以最后def.set(maAr, ...)相当于把nil存进了UserDefaults,打印当然是nil。 - 另外,Label的
text是可选类型,直接存进去虽然语法没问题,但万一Label为空,会导致数组里出现nil值,后续读取的时候容易出bug,所以我加了guard语句做校验。 - 最后提个小细节:iOS 10之后,
synchronize()已经不需要手动调用了,系统会自动处理UserDefaults的同步,所以可以删掉这行代码。
这样修改后,你再点击按钮,就能正常把Label的文本存入UserDefaults,打印出来也能看到正确的数组内容啦!
内容的提问来源于stack exchange,提问作者Bogdan59
相关产品推荐
相关产品推荐

