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

时间:2014-07-01 17:32:48

标签: ios arrays swift nsdata

我试图在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?

4 个答案:

答案 0 :(得分:63)

您可以使用getBytes的{​​{1}}方法:

NSData

更新Swift 3(Xcode 8): Swift 3有一个新类型// 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] 这是具有适当值语义的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>

答案 1 :(得分:14)

也可以使用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)

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

答案 2 :(得分:1)

如果您正在处理Data to Array(我知道我的数组将是[String]),我对此非常满意:

NSKeyedUnarchiver.unarchiveObject(with:yourData)

我希望它有所帮助

答案 3 :(得分:0)

这是一种通用的方法。

import Foundation

extension Data {
    func elements <T> () -> [T] {
        return withUnsafeBytes {
            Array(UnsafeBufferPointer<T>(start: $0, count: count/MemoryLayout<T>.size))
        }
    }
}

let array = [1, 2, 3]
let data = Data(buffer: UnsafeBufferPointer(start: array, count: array.count))
let array2: [Int] = data.elements()

array == array2
// IN THE PLAYGROUND, THIS SHOWS AS TRUE

您必须在array2行中指定类型。否则,编译器无法猜测。