Ios 为什么集合不是属性列表类型?

Ios 为什么集合不是属性列表类型?,ios,swift,nsuserdefaults,swift4.2,Ios,Swift,Nsuserdefaults,Swift4.2,我试图在用户默认值中保存一个集类型,结果得到一个 “尝试设置非属性列表对象”错误 这让我想知道,为什么Set不是属性列表类型 为什么允许使用数组和字典,但不允许使用集合 编辑:我知道存储数据的其他方法。我只是想知道是否有一个已知或估计的原因,为什么苹果决定集合不是属性列表类型 是因为集合没有数组(索引)和字典(键)这样的键吗?是因为集合无序吗?但是字典也是无序的 您需要先归档您的集合,使其成为数据对象。只有这样,才能将该数据存储为默认值 像这样: let sets: Set<String&

我试图在用户默认值中保存一个
类型,结果得到一个 “尝试设置非属性列表对象”错误

这让我想知道,为什么Set不是属性列表类型

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

编辑:我知道存储数据的其他方法。我只是想知道是否有一个已知或估计的原因,为什么苹果决定集合不是属性列表类型


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

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

像这样:

let sets: Set<String> = Set(arrayLiteral: "a","b","c")
let encodedData = NSKeyedArchiver.archivedData(withRootObject: sets)
UserDefaults.standard.setValue(encodedData, forKeyPath: "test")
let Set:Set=Set(数组并行:“a”、“b”、“c”)
让encodedData=NSKeyedArchiver.archivedData(withRootObject:sets)
UserDefaults.standard.setValue(encodedData,forKeyPath:“测试”)
然后,要取消归档数据,请这样做(然后您可以取回数据集)

如果let data=UserDefaults.standard.data(forKey:“test”),
设set=NSKeyedUnarchiver.unarchiveObject(带:data)为?设置{
打印(套)
}
至于不存档就无法存储设备的原因,以下是苹果公司的说法:

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


如您所见,如果将集合转换为
数组
数据
,则最好将其存储到
用户默认值

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

像这样:

let sets: Set<String> = Set(arrayLiteral: "a","b","c")
let encodedData = NSKeyedArchiver.archivedData(withRootObject: sets)
UserDefaults.standard.setValue(encodedData, forKeyPath: "test")
let Set:Set=Set(数组并行:“a”、“b”、“c”)
让encodedData=NSKeyedArchiver.archivedData(withRootObject:sets)
UserDefaults.standard.setValue(encodedData,forKeyPath:“测试”)
然后,要取消归档数据,请这样做(然后您可以取回数据集)

如果let data=UserDefaults.standard.data(forKey:“test”),
设set=NSKeyedUnarchiver.unarchiveObject(带:data)为?设置{
打印(套)
}
至于不存档就无法存储设备的原因,以下是苹果公司的说法:

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


如您所见,如果将集合转换为
数组
数据
,则最好将其存储到
用户默认值
属性列表表示数据,而不是实现细节。数组是一个有序列表。dict是字符串键到值的映射。“集合”是什么?它在简单文本数据中没有任何特殊意义。如果列表不能有重复项,请不要写入重复项。如果是无序的,忽略顺序。“设置为”的一切都与数据操作有关。(对于实际具有重复元素的plist集,您会期望它有什么行为?它是否无效?如果不是,它如何不仅仅是一个数组?)

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

原始(NeXTSTEP)格式的键入要简单得多:

SomeKey = {
    MyFirstProperty = ("here's", "a", "list");
    SomeOtherThing = "I'm a string";
};
苹果使用OSX转换为XML,这使得键入变得更加困难,但基本方法是相同的。(在OS X的早期,苹果采取了很多措施将Java集成到系统中,包括更多地依赖XML。回顾过去,这些措施中的许多可能是不幸的,但在当时是有意义的。)

plist解决了与JSON相同的问题。它们提供了编码原始数据所需的最小类型集,而不是实现算法所需的数据结构


我并不是说plists是由一些数学第一原理创造出来的。如果NSSet是配置数据中非常常见的一种类型,那么我确信它会进入到该格式中。但它们并不是用来保存任意应用程序数据的通用方法,NSUserDefaults也不是。数组是一个有序列表。dict是字符串键到值的映射。“集合”是什么?它在简单文本数据中没有任何特殊意义。如果列表不能有重复项,请不要写入重复项。如果是无序的,忽略顺序。“设置为”的一切都与数据操作有关。(对于实际具有重复元素的plist集,您会期望它有什么行为?它是否无效?如果不是,它如何不仅仅是一个数组?)

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

原始(NeXTSTEP)格式的键入要简单得多:

SomeKey = {
    MyFirstProperty = ("here's", "a", "list");
    SomeOtherThing = "I'm a string";
};
苹果使用OSX转换为XML,这使得键入变得更加困难,但基本方法是相同的。(在OSX的早期,苹果做了很多动作