数组 – 如何让NSCoder对Swift结构数组进行编码/解码?

前端之家收集整理的这篇文章主要介绍了数组 – 如何让NSCoder对Swift结构数组进行编码/解码?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个必须符合NSCoding并且包含一组UInt64值的对象.如何使用NSCoder对其进行编码/解码?额外问题:如何最紧凑地编码? (它必须进入保存的Game Center状态数据,其大小有限.)

理想情况下,我只想写一个Int,它是数组的大小n,然后写入n次64位的UInt64,并以类似方式读取它.我可以这样做吗?

coder.encodeObject(values,forKey:“v”)不起作用.

  1. class MyObject: NSCoding {
  2.  
  3. private var values: [UInt64]
  4.  
  5. // …
  6.  
  7. // MARK: - NSCoding
  8.  
  9. required init(coder decoder: NSCoder) {
  10. // ???
  11. }
  12.  
  13. func encodeWithCoder(coder: NSCoder) {
  14. // ???
  15. }
  16.  
  17.  
  18. }
这是一个将UInt64数组编码为的可能解决方
一个字节数组.它的灵感来自 How to serialize C array with NSCoding?的答案.
  1. class MyObject: NSObject,NSCoding {
  2.  
  3. var values: [UInt64] = []
  4.  
  5. init(values : [UInt64]) {
  6. self.values = values
  7. }
  8.  
  9. // MARK: - NSCoding
  10. required init(coder decoder: NSCoder) {
  11. super.init()
  12. var count = 0
  13. // decodeBytesForKey() returns an UnsafePointer<UInt8>,pointing to immutable data.
  14. let ptr = decoder.decodeBytesForKey("values",returnedLength: &count)
  15. // If we convert it to a buffer pointer of the appropriate type and count ...
  16. let buf = UnsafeBufferPointer<UInt64>(start: UnsafePointer(ptr),count: count/sizeof(UInt64))
  17. // ... then the Array creation becomes easy.
  18. values = Array(buf)
  19. }
  20.  
  21. func encodeWithCoder(coder: NSCoder) {
  22. // This encodes both the number of bytes and the data itself.
  23. coder.encodeBytes(UnsafePointer(values),length: values.count * sizeof(UInt64),forKey: "values")
  24. }
  25. }

测试:

  1. let obj = MyObject(values: [1,2,3,UInt64.max])
  2. let data = NSKeyedArchiver.archivedDataWithRootObject(obj)
  3.  
  4. let dec = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! MyObject
  5. print(dec.values) // [1,18446744073709551615]

更新Swift 3(Xcode 8):

  1. class MyObject: NSObject,NSCoding {
  2.  
  3. var values: [UInt64] = []
  4.  
  5. init(values : [UInt64]) {
  6. self.values = values
  7. }
  8.  
  9. // MARK: - NSCoding
  10. required init(coder decoder: NSCoder) {
  11. super.init()
  12. var count = 0
  13. // decodeBytesForKey() returns an UnsafePointer<UInt8>?,pointing to immutable data.
  14. if let ptr = decoder.decodeBytes(forKey: "values",returnedLength: &count) {
  15. // If we convert it to a buffer pointer of the appropriate type and count ...
  16. let numValues = count / MemoryLayout<UInt64>.stride
  17. ptr.withMemoryRebound(to: UInt64.self,capacity: numValues) {
  18. let buf = UnsafeBufferPointer<UInt64>(start: UnsafePointer($0),count: numValues)
  19. // ... then the Array creation becomes easy.
  20. values = Array(buf)
  21. }
  22. }
  23. }
  24.  
  25. public func encode(with coder: NSCoder) {
  26. // This encodes both the number of bytes and the data itself.
  27. let numBytes = values.count * MemoryLayout<UInt64>.stride
  28. values.withUnsafeBufferPointer {
  29. $0.baseAddress!.withMemoryRebound(to: UInt8.self,capacity: numBytes) {
  30. coder.encodeBytes($0,length: numBytes,forKey: "values")
  31. }
  32. }
  33. }
  34. }
  35.  
  36.  
  37. let obj = MyObject(values: [1,UInt64.max])
  38. let data = NSKeyedArchiver.archivedData(withRootObject: obj)
  39.  
  40. let dec = NSKeyedUnarchiver.unarchiveObject(with: data) as! MyObject
  41. print(dec.values) // [1,18446744073709551615]

猜你在找的Swift相关文章