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

问题描述 投票:0回答:2

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

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

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

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

是因为Sets没有像Arrays(index)和Dictionaries(key)这样的键吗?是因为套装是无序的吗?但字典也是无序的......

ios swift nsuserdefaults swift4.2
2个回答
0
投票

属性列表表示数据,而不是实现细节。数组是有序列表。 dict是字符串键到值的映射。什么是“套装?”它并不意味着简单的文本数据有什么特别之处。如果列表不能有重复项,请不要写重复项。如果它是无序的,请忽略该订单。 “像集一样”的一切都与操纵数据有关。 (对于实际上确实存在重复元素的plist-set,你会期望什么行为?它会无效吗?如果没有,它怎么不仅仅是一个数组?)

属性列表不是一般的对象树序列化工具。这就是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。回想起来,很多这些动作可能都很不幸,但当时它们是有道理的。)

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

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


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

© www.soinside.com 2019 - 2024. All rights reserved.