为什么Set不是属性列表类型?

时间:2019-02-21 07:19:17

标签: ios swift nsuserdefaults swift4.2

我试图在用户默认设置中保存Set<String>类型,并得到一个 “尝试设置非属性列表对象”错误。

这让我感到奇怪,为什么Set不是属性列表类型?

为什么允许使用数组和字典,但不允许使用集合?

编辑:我知道其他存储数据的方法。我只是想知道苹果公司是否确定Set不是属性列表类型,是否有已知或估计的原因。

是因为集没有像数组(索引)和字典(键)这样的键?是因为集合是无序的吗?但是字典也是无序的。

2 个答案:

答案 0 :(得分:0)

您需要先存档您的集合,使其成为Data对象。只有这样,您才能将这些数据存储为默认值。

像这样:

let sets: Set<String> = Set(arrayLiteral: "a","b","c")
let encodedData = NSKeyedArchiver.archivedData(withRootObject: sets)
UserDefaults.standard.setValue(encodedData, forKeyPath: "test")

然后要取消存档数据,请按以下步骤进行操作(然后您可以取回数据集)

if let data = UserDefaults.standard.data(forKey: "test"),
    let set = NSKeyedUnarchiver.unarchiveObject(with: data) as? Set<String> {
    print(set)
}

关于为什么不存档就无法存储您的集合的原因,这就是Apple所说的:

  

默认对象必须是属性列表,即(或   对于集合,是NSData,NSString,   NSNumber,NSDate,NSArray或NSDictionary。如果要存储任何   其他类型的对象,通常应将其归档以创建一个   NSData的实例。

https://developer.apple.com/documentation/foundation/userdefaults

如您所见,如果将集合转换为ArrayData,最好将其存储到UserDefaults

答案 1 :(得分:0)

属性列表代表数据,而不是实现细节。数组是有序列表。字典是字符串键到值的映射。什么是“集合”?这并不意味着简单文本数据中有什么特别的地方。如果列表不能重复,请不要重复。如果是无序的,则忽略该顺序。所有“类集”都与数据操作有关。 (您会从plist集中期望实际上 did 具有重复元素的什么行为?会无效吗?如果不是,那么它不仅是数组吗?)

属性列表不是通用的对象树序列化工具。那就是NSCoder的目的。它们主要是为诸如Info.plist之类的可写配置而设计的,并且可以用任何语言进行解析。 NSUserDefaults也不是通用的数据存储(如果是,则称为“ NSApplicationDataStore”或类似名称)。它旨在以用户可以手工编辑的方式存储用户配置数据。

原始(NeXTSTEP)格式更容易输入:

SomeKey = {
    MyFirstProperty = ("here's", "a", "list");
    SomeOtherThing = "I'm a string";
};

Apple随OS X转换为XML,这使得键入起来更加困难,但是基本方法是相同的。 (在OS X的早期,Apple采取了很多措施将Java集成到系统中,包括更多地依赖XML,包括formal DTDs。回想起来,其中许多举措可能是不幸的,但在时间。)

列表可以解决与JSON相同的问题。它们提供了用于编码原始数据而不是用于实现算法的数据结构的最小类型集。

我并不是说plists是根据一些数学上的第一原理而创建的。如果NSSet是配置数据中非常常见的类型,我敢肯定它会找到格式。但是,它们并不是被发明为保存任意应用程序数据的通用方法,NSUserDefaults也不是。