You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:24:07