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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:12:08  来源:igfitidea点击:

Create an Array in Swift from an NSData Object

iosarraysswiftnsdata

提问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 COpaquePointerto the data with data.bytesbut 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 getBytesmethod 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 Datawhich is a wrapper for NS(Mutable)Datawith 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 Sequenceprotocol:

也可以使用 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 Sequenceprotocol 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 array2line. 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

我希望它有帮助