从NSData对象在Swift中创建一个数组

tas*_*ari 34 arrays nsdata ios swift

我试图在swift中将一个整数数组存储到磁盘.我可以将它们放入要存储的NSData对象中,但是将它们放回到数组中是很困难的.我可以获得原始COpaquePointer的数据data.bytes但无法找到一种方法来使用该指针初始化一个新的swift数组.有谁知道怎么做?

import Foundation

var arr : UInt32[] = [32,4,123,4,5,2];

let data = NSData(bytes: arr, length: arr.count * sizeof(UInt32))

println(data)  //data looks good in the inspector

// now get it back into an array?
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 66

您可以使用以下getBytes方法NSData:

// the number of elements:
let count = data.length / sizeof(UInt32)

// create array of appropriate length:
var array = [UInt32](count: count, repeatedValue: 0)

// copy bytes into array
data.getBytes(&array, length:count * sizeof(UInt32))

print(array)
// Output: [32, 4, 123, 4, 5, 2]
Run Code Online (Sandbox Code Playgroud)

更新Swift 3(Xcode 8): Swift 3有一个新类型struct Data ,它是一个NS(Mutable)Data具有适当值语义的包装器.存取方法略有不同.

数组到数据:

var arr: [UInt32] = [32, 4, UInt32.max]
let data = Data(buffer: UnsafeBufferPointer(start: &arr, count: arr.count))
print(data) // <20000000 04000000 ffffffff>
Run Code Online (Sandbox Code Playgroud)

数组到数组:

let arr2 = data.withUnsafeBytes {
    Array(UnsafeBufferPointer<UInt32>(start: $0, count: data.count/MemoryLayout<UInt32>.stride))
}
print(arr2) // [32, 4, 4294967295]
Run Code Online (Sandbox Code Playgroud)


Dan*_*uce 14

也可以使用a来实现这一点UnsafeBufferPointer,它本质上是一个"数组指针",因为它实现了Sequence协议:

let data = NSData(/* ... */)

// Have to cast the pointer to the right size
let pointer = UnsafePointer<UInt32>(data.bytes)
let count = data.length / 4

// Get our buffer pointer and make an array out of it
let buffer = UnsafeBufferPointer<UInt32>(start:pointer, count:count)
let array = [UInt32](buffer)
Run Code Online (Sandbox Code Playgroud)

这样就不需要首先用重复的元素初始化一个空数组,然后覆盖它,虽然我不知道它是否更快.因为它使用Sequence协议这意味着迭代而不是快速内存复制,但我不知道它是否在传递缓冲区指针时进行了优化.然后,我不确定"创建一个具有X个相同元素的空数组"初始化程序的速度有多快.

  • 看起来getBytes比这个快得多.对于使用"数组指针"的1349890字节需要0.034秒,而getBytes只需要0.005秒 (5认同)