2

我想将 UInt16 转换为 UInt8 数组,但收到以下错误消息:

'init' 不可用:使用 'withMemoryRebound(to:capacity:_)' 临时将内存视为另一种布局兼容类型。

编码:

    let statusByte: UInt8 = UInt8(status)
    let lenghtByte: UInt16 = UInt16(passwordBytes.count)

    var bigEndian = lenghtByte.bigEndian

    let bytePtr = withUnsafePointer(to: &bigEndian) {
        UnsafeBufferPointer<UInt8>(start: UnsafePointer($0), count: MemoryLayout.size(ofValue: bigEndian))
    }
4

2 回答 2

9

如错误消息所示,您必须使用withMemoryRebound() 将指针重新解释为指向UInt16的指针UInt8

let bytes = withUnsafePointer(to: &bigEndian) {
    $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: bigEndian)) {
        Array(UnsafeBufferPointer(start: $0, count: MemoryLayout.size(ofValue: bigEndian)))
    }
}

闭包使用指针 ( ) 调用,这些指针$0仅在闭包的生命周期内有效,并且不得传递给外部以供以后使用。这Array就是创建 an 并将其用作返回值的原因。

然而,有一个更简单的解决方案:

let bytes = withUnsafeBytes(of: &bigEndian) { Array($0) }

说明: withUnsafeBytes调用带有 a 的闭包UnsafeRawBufferPointer来存储bigEndian变量。由于UnsafeRawBufferPointer是 a Sequenceof UInt8,因此可以使用 从中创建一个数组Array($0)

于 2017-06-04T18:54:23.493 回答
7

您可以扩展 Numeric 协议并创建一个数据属性,如下所示:

斯威夫特 4 或更高版本

extension Numeric {
    var data: Data {
        var source = self
        return Data(bytes: &source, count: MemoryLayout<Self>.size)
    }
}

由于 Swift 3 Data 符合,RandomAccessCollection因此您可以从 UInt16 bigEndian 数据创建一个字节数组:

extension Data {
    var array: [UInt8] { return Array(self) }
}

let lenghtByte = UInt16(8)
let bytePtr = lenghtByte.bigEndian.data.array   // [0, 8]
于 2017-06-04T18:24:56.837 回答