我有一个必须符合NSCoding
且包含UInt64
值数组的对象。我怎么能用/对其进行编码/解码NSCoder
?额外的问题:如何编码最紧凑?(它必须进入保存的Game
Center状态数据,其大小是有限的。)
理想情况下,我只想写一个等于数组Int
大小n
的an ,然后写n
乘a的64位乘以UInt64
类似的方式读取它。我可以这样做吗?
coder.encodeObject(values, forKey: "v")
不起作用。
class MyObject: NSCoding {
private var values: [UInt64]
// …
// MARK: - NSCoding
required init(coder decoder: NSCoder) {
// ???
}
func encodeWithCoder(coder: NSCoder) {
// ???
}
}
这是将UInt64
数组编码为字节数组的可能解决方案。它的灵感来自于如何使用NSCoding序列化C数组?。
class MyObject: NSObject, NSCoding {
var values: [UInt64] = []
init(values : [UInt64]) {
self.values = values
}
// MARK: - NSCoding
required init(coder decoder: NSCoder) {
super.init()
var count = 0
// decodeBytesForKey() returns an UnsafePointer<UInt8>, pointing to immutable data.
let ptr = decoder.decodeBytesForKey("values", returnedLength: &count)
// If we convert it to a buffer pointer of the appropriate type and count ...
let buf = UnsafeBufferPointer<UInt64>(start: UnsafePointer(ptr), count: count/sizeof(UInt64))
// ... then the Array creation becomes easy.
values = Array(buf)
}
func encodeWithCoder(coder: NSCoder) {
// This encodes both the number of bytes and the data itself.
coder.encodeBytes(UnsafePointer(values), length: values.count * sizeof(UInt64), forKey: "values")
}
}
测试:
let obj = MyObject(values: [1, 2, 3, UInt64.max])
let data = NSKeyedArchiver.archivedDataWithRootObject(obj)
let dec = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! MyObject
print(dec.values) // [1, 2, 3, 18446744073709551615]
Swift 3(Xcode 8)更新:
class MyObject: NSObject, NSCoding {
var values: [UInt64] = []
init(values : [UInt64]) {
self.values = values
}
// MARK: - NSCoding
required init(coder decoder: NSCoder) {
super.init()
var count = 0
// decodeBytesForKey() returns an UnsafePointer<UInt8>?, pointing to immutable data.
if let ptr = decoder.decodeBytes(forKey: "values", returnedLength: &count) {
// If we convert it to a buffer pointer of the appropriate type and count ...
let numValues = count / MemoryLayout<UInt64>.stride
ptr.withMemoryRebound(to: UInt64.self, capacity: numValues) {
let buf = UnsafeBufferPointer<UInt64>(start: UnsafePointer($0), count: numValues)
// ... then the Array creation becomes easy.
values = Array(buf)
}
}
}
public func encode(with coder: NSCoder) {
// This encodes both the number of bytes and the data itself.
let numBytes = values.count * MemoryLayout<UInt64>.stride
values.withUnsafeBufferPointer {
$0.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: numBytes) {
coder.encodeBytes($0, length: numBytes, forKey: "values")
}
}
}
}
let obj = MyObject(values: [1, 2, 3, UInt64.max])
let data = NSKeyedArchiver.archivedData(withRootObject: obj)
let dec = NSKeyedUnarchiver.unarchiveObject(with: data) as! MyObject
print(dec.values) // [1, 2, 3, 18446744073709551615]
问题内容: 背景 我正在尝试使用NSCoding协议对String样式的枚举进行编码,但是我遇到了转换为String和从String返回的错误。 解码和编码时出现以下错误: 字符串不可转换为舞台 额外参数ForKey:通话中 码 问题答案: 您需要将枚举值与原始值进行转换。在Swift 1.2(Xcode 6.3)中,如下所示: Swift 1.1(Xcode 6.1),代替: 迅速1.0(6.0
我在MySql中有两个表 部分 类别 如何从PHP解码JSON以获得如下结果: {节:[ {节名:"节1",分类列表:[{分类名称:"分类1"},{分类名称:"分类2"}]}, {节名:"节1",分类列表:[{分类名称:"#########################################################################################
问题内容: 我正在尝试在Go中解码一些json,但某些字段不会被解码。在此处查看在浏览器中运行的代码: 我究竟做错了什么? 我只需要MX记录,所以没有定义其他字段。据我从godoc了解到,您不需要定义不需要/不需要的字段。 问题答案: 按照有关json.Unmarshal的go documentaiton 所述,您只能对导出的字段进行解码,主要原因是外部软件包(例如)无法访问未导出的字段。 如果您
问题内容: 这是我的JSON 这是我希望将其保存到的结构(不完整) 我看过Apple的有关解码嵌套结构的文档,但是我仍然不明白如何正确执行JSON的不同级别。任何帮助都感激不尽。 问题答案: 另一种方法是创建一个与JSON紧密匹配的中间模型(借助于quicktype.io之类的工具),让Swift生成对它进行解码的方法,然后在最终数据模型中挑选所需的片段: 如果将来它包含多个值,这还使您可以轻松地
问题内容: 如果我编码这样的字符串: 它不能逃脱斜线。 我搜索并找到了此Objective C代码: 有没有更简单的方法来编码URL,否则,如何在Swift中编写此代码? 问题答案: 迅捷3 在Swift 3中有 输出: 测试%2Ftest 斯威夫特1 在iOS 7及更高版本中, 输出: 测试%2Ftest 以下是有用的(倒置)字符集: 如果要转义其他字符集,请创建一个字符集: 添加了“ =”字符