自定义Sheet对象数组存取崩溃问题及saveNotesArray调用位置咨询
问题分析与解决方案:自定义Sheet对象存储UserDefaults崩溃问题
嘿,我看到你在用自定义Sheet对象存笔记到UserDefaults时崩溃了,这是个新手常遇到的问题,咱们一步步拆解解决它~
首先,当前的实现方式是不正确的,这就是崩溃的核心原因:UserDefaults并不支持直接存储自定义的Swift类对象(比如你的Sheet类),它只能存储特定类型的数据——像字符串、数字、布尔值,或者包含这些类型的数组/字典,以及遵循Codable协议的对象,或者继承自NSObject并遵循NSCoding协议的对象。你的Sheet类既没有遵循这些协议,直接把[Sheet]存入UserDefaults自然会触发崩溃。
解决方案:让Sheet类支持序列化
最简洁的方案是让Sheet类遵循Swift的Codable协议(因为你的属性都是String类型,Swift会自动为你生成序列化/反序列化的代码,不需要手动写)。
修改Sheet类代码
class Sheet: Codable { var title = "" var content = "" }
调整保存与读取逻辑
接下来要修改保存和读取的代码,把数组编码成Data再存入UserDefaults;读取时则从Data解码回[Sheet]:
重写saveNotesArray函数
func saveNotesArray() { do { let data = try JSONEncoder().encode(notes) UserDefaults.standard.set(data, forKey: "notes") // iOS 12+之后synchronize()已废弃,系统会自动处理同步 // UserDefaults.standard.synchronize() } catch { print("保存笔记失败:\(error.localizedDescription)") } }
调整viewDidLoad中的读取逻辑
override func viewDidLoad() { super.viewDidLoad() if let data = UserDefaults.standard.data(forKey: "notes") { do { notes = try JSONDecoder().decode([Sheet].self, from: data) } catch { print("读取笔记失败:\(error.localizedDescription)") } } }
saveNotesArray函数应该调用的位置
你需要在笔记数据发生变化的所有场景调用这个函数,确保数据及时保存:
- 删除笔记后:在删除逻辑的末尾添加调用,因为数组已经被修改
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { notes.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .automatic) saveNotesArray() // 添加这行保存操作 } - 用户编辑完笔记返回后:因为
Sheet是引用类型,用户在NoteContentVC里修改的内容会直接同步到notes数组中,所以可以在viewWillAppear里调用保存,确保每次页面显示时都保存最新状态override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.tableView.reloadData() saveNotesArray() // 添加这行 } - 移除当前prepare中的无效调用:你现在在
prepare(for:sender:)里调用了saveNotesArray,但这时候新笔记还没被编辑,内容是空的,这个调用没有意义,建议删掉。
另外,如果你的NoteContentVC有明确的“保存”按钮,也可以在用户点击该按钮时直接触发保存逻辑,这样更精准。
额外提示
- UserDefaults适合存储小量数据,如果你的笔记数量多、内容长,建议改用Core Data、Realm或者本地文件存储,UserDefaults并不是为大量数据设计的。
- 记得移除
UserDefaults.standard.synchronize(),这个方法在iOS 12之后已经被废弃,系统会自动处理UserDefaults的同步操作。
内容的提问来源于stack exchange,提问作者Francis
相关产品推荐
相关产品推荐

