如何将Swift Set存入NSUserDefaults?转NSMutableSet仍报错
Swift Set 存入 UserDefaults 的正确姿势
这个问题我之前也踩过坑!你遇到的报错本质原因是:UserDefaults 只支持存储「属性列表类型」,也就是 NSString、NSNumber、NSDate、NSData、NSArray、NSDictionary 这些,NSMutableSet 并不在这个列表里,所以直接存就会触发那个「非属性列表对象」的错误。
至于你说能读取到 NSMutableSet,大概率是之前存储的时候其实用了属性列表兼容的格式(比如把 Set 转成 Array 存的),然后通过 UserDefaults 的 mutableSetValue(forKey:) 方法,内部帮你把数组转成了可变集合,但这并不代表可以直接存 NSMutableSet。
下面给你两种常用的解决方案:
1. 存储基础类型的 Set(String/Int 等)
最简单的方式是把 Set 转换成 Array 存储,读取时再转回 Set:
存储代码
let myStringSet: Set<String> = ["foo", "bar", "baz"] // 把 Set 转成 Array 存入 UserDefaults UserDefaults.standard.set(Array(myStringSet), forKey: "MyStringSetKey")
读取代码
// 先取出 Array,再转成 Set if let storedArray = UserDefaults.standard.array(forKey: "MyStringSetKey") as? [String] { let retrievedSet = Set(storedArray) // 这里就可以使用 retrievedSet 了 print(retrievedSet) }
2. 存储自定义对象的 Set
如果你的 Set 里是自定义对象,需要先把对象序列化成 Data,再存入 UserDefaults,推荐用 Swift 自带的 Codable 协议来实现:
第一步:让自定义对象遵循 Codable
struct CustomItem: Codable { let id: Int let name: String }
存储代码
let customSet: Set<CustomItem> = [ CustomItem(id: 1, name: "foo"), CustomItem(id: 2, name: "bar") ] do { // 把 Set 编码成 Data let encodedData = try JSONEncoder().encode(customSet) UserDefaults.standard.set(encodedData, forKey: "MyCustomSetKey") } catch { print("编码失败:\(error.localizedDescription)") }
读取代码
if let storedData = UserDefaults.standard.data(forKey: "MyCustomSetKey") { do { // 把 Data 解码回 Set let retrievedSet = try JSONDecoder().decode(Set<CustomItem>.self, from: storedData) // 使用 retrievedSet retrievedSet.forEach { print($0.name) } } catch { print("解码失败:\(error.localizedDescription)") } }
内容的提问来源于stack exchange,提问作者Senseful
相关产品推荐
相关产品推荐

