【发布时间】:2014-06-13 02:32:04
【问题描述】:
我正在尝试从一个字节数组创建一个NSDatavar。
在 Obj-C 中我可能会这样做:
NSData *endMarker = [[NSData alloc] initWithBytes:{ 0xFF, 0xD9 }, length: 2]
我无法在 Swift 中找到一个有效的等价物。
【问题讨论】:
我正在尝试从一个字节数组创建一个NSDatavar。
在 Obj-C 中我可能会这样做:
NSData *endMarker = [[NSData alloc] initWithBytes:{ 0xFF, 0xD9 }, length: 2]
我无法在 Swift 中找到一个有效的等价物。
【问题讨论】:
NSData 有一个初始化器,它接受一个bytes 指针:init(bytes: UnsafeMutablePointer <Void>, length: Int)。 UnsafePointer 参数可以接受各种不同的东西,包括一个简单的 Swift 数组,因此您可以使用与 Objective-C 中几乎相同的语法。当您传递数组时,您需要确保将其识别为 UInt8 数组,否则 Swift 的类型推断将假定您的意思是创建一个 Int 数组。
var endMarker = NSData(bytes: [0xFF, 0xD9] as [UInt8], length: 2)
您可以在 Apple 的 Interacting with C APIs 文档中阅读有关不安全指针参数的更多信息。
【讨论】:
Int 数组,而不是 Byte 数组。
Byte在swift1.2中被删除,改用UInt8。
var foo : Byte[] = [0xff, 0xD9]
var data = NSData(bytes: foo, length: foo.count)
println("\(data)")
输出:ff d9
var data = NSData(bytes: [0xFF, 0xD9] as Byte[], length: 2)
println("\(data)")
输出:ff d9
编辑:啊,你必须写'as Byte[]',所以结果是一样的
为 Swift 2.2 更新
var foo:[UInt8] = [0xff, 0xD9]
var data = NSData(bytes: foo, length: foo.count)
print("\(data)")
输出:ff d9
var data = NSData(bytes: [0xFF, 0xD9] as [UInt8], length: 2)
print("\(data)")
输出:ff d9
【讨论】:
Byte 了。而不是Byte[],写[Uint8]
UInt8(拼写)
你不需要扩展 Data,在 Swift 3 中你可以这样做:
let bytes:[UInt8] = [0x00, 0x01, 0x02, 0x03]
let data = Data(bytes: bytes)
print(data as NSData)
打印“”
再次获取字节数组:
let byteArray:[UInt8] = [UInt8](data)
【讨论】:
Swift 3 扩展
extension Data {
init<T>(fromArray values: [T]) {
var values = values
self.init(buffer: UnsafeBufferPointer(start: &values, count: values.count))
}
func toArray<T>(type: T.Type) -> [T] {
return self.withUnsafeBytes {
[T](UnsafeBufferPointer(start: $0, count: self.count/MemoryLayout<T>.stride))
}
}
}
用法
let bytes:[UInt8] = [0x00, 0xf4, 0x7c]
let data = Data(fromArray: someBytes)
print(data as NSData)
let bytes = data.toArray(type: UInt8.self)
print(bytes)
【讨论】:
对于 Swift 5,我创建了另一个运行良好的 Data 扩展。
extension Data {
init<T>(fromArray values: [T]) {
var values = values
self.init(buffer: UnsafeBufferPointer(start: &values, count: values.count))
}
func toArray<T>(type: T.Type) -> [T] {
let value = self.withUnsafeBytes {
$0.baseAddress?.assumingMemoryBound(to: T.self)
}
return [T](UnsafeBufferPointer(start: value, count: self.count / MemoryLayout<T>.stride))
}
}
示例用法
let data = Data(fromArray: [1, 2, 3, 4, 5])
let array = data.toArray(type: Int.self)
print(array)
// [1, 2, 3, 4, 5]
【讨论】: