*** Bool 编码为数字属性列表片段。属性列表编码器
Posted
技术标签:
【中文标题】*** Bool 编码为数字属性列表片段。属性列表编码器【英文标题】:Top-level Bool encoded as number property list fragment. PropertyListEncoder 【发布时间】:2018-11-06 17:53:35 【问题描述】:我有这个通用函数可以保存在 NSUserDefaults 中,通常可以使用,但现在我想保存一个布尔值,但出现错误。我找不到任何东西,我不明白为什么它不起作用。
extension UserDefaults
func saveUserDefaults<T: Codable>(withKey key: String, myType: T) throws
do
let data = try PropertyListEncoder().encode(myType)
UserDefaults.standard.set(data, forKey: key)
print("Saved for Key:", key)
catch let error
print("Save Failed")
throw error
我这样称呼它:
try! UserDefaults().saveUserDefaults(withKey: "String", myType: false)
这是我得到的错误。我知道还有另一种保存布尔值的方法,但我想知道为什么它不能这样工作?
线程 1:致命错误:“尝试!”表达式意外引发错误: Swift.EncodingError.invalidValue(假, Swift.EncodingError.Context(codingPath: [], debugDescription: "编码为数字属性列表片段的*** Bool。", 底层错误:无))
谢谢!
【问题讨论】:
属性列表总是需要字典或数组作为***对象,比较developer.apple.com/documentation/foundation/…。 这不是我设置密钥的原因吗?false
是布尔值,而不是字典。它也会因整数或字符串而失败。
【参考方案1】:
正如@Martin 所说,PropertyListEncoder 仅支持顶层的属性列表,而不支持像 NSNumber 这样的属性列表的单个片段。 一个非常简单(虽然不是很优雅)的解决方法是将任何对象包装到数组中:
let data = try PropertyListEncoder().encode([myType])
UserDefaults.standard.set(data, forKey: key)
并将其解码为:
let arr = try PropertyListDecoder().decode([T].self, from: data)
return arr.first
见https://www.marisibrothers.com/2018/07/workaround-for-serializing-codable-fragments.html
【讨论】:
这个真的很有用!【参考方案2】:PropertyListEncoder
编码为“属性列表”,这始终是
数组或字典,比较PropertyListSerialization。
因此
let data = try PropertyListEncoder().encode(myType)
如果myType
是Bool
(或任何不是数组的东西)则失败
或字典)。
属性列表中的可能对象也受到限制,它们只能是
NSData
、NSString
、NSArray
、NSDictionary
、NSDate
或 NSNumber
- 或 Swift 类型
桥接到这些 Foundation 类型之一。
【讨论】:
【参考方案3】:您无需编码布尔值即可保存到 UserDefaults。您可以通过调用直接将布尔值保存到 UserDefaults 中
let myValue: Bool = false
UserDefaults.standard.set(myValue, forKey: "key")
请参阅 Apple 文档:UserDefaults.set(_:forKey:)。
我看到您有一个采用 Codable 类型的函数,对其进行编码,然后将其保存到 UserDefaults。正如 Martin R 指出的那样,您将不得不修改该函数并检查是否可以将传递的对象直接保存到 UserDefaults 而无需编码。
【讨论】:
以上是关于*** Bool 编码为数字属性列表片段。属性列表编码器的主要内容,如果未能解决你的问题,请参考以下文章
VB大神赐教!怎么让下拉列表combobox只能选择不能写入其他值?
Operator '||' cannot be applied to operands of type 'bool?' and 'bool?'(代码片段
Operator '||' cannot be applied to operands of type 'bool?' and 'bool?'(代码片段