ios 在 Swift 中从 NSData 对象创建一个数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24516170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create an Array in Swift from an NSData Object
提问by tassinari
I'm trying to store an array of integers to disk in swift. I can get them into an NSData object to store, but getting them back out into an array is difficult. I can get a raw COpaquePointer
to the data with data.bytes
but can't find a way to initialize a new swift array with that pointer. Does anyone know how to do it?
我正在尝试将整数数组快速存储到磁盘。我可以将它们放入一个 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?
回答by Martin R
You can use the getBytes
method of NSData
:
您可以使用以下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]
Update for Swift 3 (Xcode 8):Swift 3 has a new type struct Data
which is a wrapper for NS(Mutable)Data
with proper value semantics.
The accessor methods are slightly different.
Swift 3 (Xcode 8) 更新:Swift 3 有一个新类型struct Data
,它是NS(Mutable)Data
具有适当值语义的包装器。访问器方法略有不同。
Array to Data:
数组到数据:
var arr: [UInt32] = [32, 4, UInt32.max]
let data = Data(buffer: UnsafeBufferPointer(start: &arr, count: arr.count))
print(data) // <20000000 04000000 ffffffff>
Data to Array:
数据到数组:
let arr2 = data.withUnsafeBytes {
Array(UnsafeBufferPointer<UInt32>(start: let arr: [UInt32] = [32, 4, UInt32.max]
let data = Data(buffer: UnsafeBufferPointer(start: arr, count: arr.count))
print(data) // <20000000 04000000 ffffffff>
, count: data.count/MemoryLayout<UInt32>.stride))
}
print(arr2) // [32, 4, 4294967295]
Update for Swift 5:
Swift 5 更新:
Array to Data:
数组到数据:
var arr2 = Array<UInt32>(repeating: 0, count: data.count/MemoryLayout<UInt32>.stride)
_ = arr2.withUnsafeMutableBytes { data.copyBytes(to: 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)
) }
print(arr2) // [32, 4, 4294967295]
Data to Array:
数据到数组:
import Foundation
extension Data {
func elements <T> () -> [T] {
return withUnsafeBytes {
Array(UnsafeBufferPointer<T>(start: ##代码##, 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
回答by Daniel Bruce
It's also possible to do this using an UnsafeBufferPointer
, which is essentially an "array pointer", as it implements the Sequence
protocol:
也可以使用 an 来做到这一点UnsafeBufferPointer
,它本质上是一个“数组指针”,因为它实现了Sequence
协议:
This eliminates the need for initializing an empty array with duplicated elements first, to then overwrite it, although I have no idea if it's any faster. As it uses the Sequence
protocol this implies iteration rather than fast memory copy, though I don't know if it's optimized when passed a buffer pointer. Then again, I'm not sure how fast the "create an empty array with X identical elements" initializer is either.
这消除了首先使用重复元素初始化空数组然后覆盖它的需要,尽管我不知道它是否更快。由于它使用Sequence
协议,这意味着迭代而不是快速内存复制,尽管我不知道在传递缓冲区指针时是否对其进行了优化。再说一次,我不确定“创建一个具有 X 个相同元素的空数组”初始化程序的速度有多快。
回答by William Entriken
Here is a generic way to do it.
这是一个通用的方法。
##代码##You must specify the type in the array2
line. Otherwise, the compiler cannot guess.
您必须array2
在行中指定类型。否则编译器无法猜测。
回答by Michel Go?i
If you are dealing with Data to Array (I know for sure my array is going to be [String]), I am quite happy with this:
如果您正在处理数据到数组(我确定我的数组将是 [String]),我对此非常满意:
NSKeyedUnarchiver.unarchiveObject(with: yourData)
NSKeyedUnarchiver.unarchiveObject(with: yourData)
I hope it helps
我希望它有帮助