Swift 5 转换UnsafeBufferPointer 这些内存函数是否相同

Are these memory functions the same for Swift 5 Conversion UnsafeBufferPointer

我正在对我不太了解的代码进行一些 Swift5 转换,这些代码来自以前的开发人员。我得到:

'withUnsafeBytes' is deprecated: use withUnsafeBytes(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R` instead

用于:

func toArray<T>(type: T.Type) -> [T] {
    return self.withUnsafeBytes {
        [T](UnsafeBufferPointer(start: [=11=], count: self.count/MemoryLayout<T>.stride))
    }
}

我想用这个替换它,但我不确定它是否做同样的事情:

func toArray<T>(type: T.Type) -> [T] where T: ExpressibleByIntegerLiteral {
    var array = [T](repeating: 0, count: self.count/MemoryLayout<T>.stride)
    _ = array.withUnsafeMutableBytes { copyBytes(to: [=12=]) }
    return array
}

在这两个 fx 的上下文中使用:

static func extractPacketSizeFromIV(iv: Data) -> Int32? {
    let array = iv.toArray(type: Int32.self)
    guard array.count == 4 else { return nil }

    let r0 = array[0].bigEndian
    let r1 = array[1].bigEndian
    let r2 = array[2].bigEndian

    return r2 ^ r1 ^ r0
}

static func extractGuidFromIV(iv: Data) -> Int32? {
    let array = iv.toArray(type: Int32.self)
    guard array.count == 4 else { return nil }

    let r0 = array[0].bigEndian
    let r1 = array[1].bigEndian
    let r2 = array[2].bigEndian
    let r3 = array[3].bigEndian

    return r3 ^ r2 ^ r1 ^ r0
}

首先,你的toArray是在Data的扩展中定义的,对吧?

(写问题的时候请把这些事情说清楚。)

在您的用例中,您的代码的工作方式与之前开发人员的代码相同,但我会像这样在Swift 5 中编写等效代码:

func toArray<T>(type: T.Type) -> [T] {
    return self.withUnsafeBytes {
        [T]([=10=].bindMemory(to: type))
    }
}

bindMemory(to: type) 根据从新的 withUnsafeBytes 传递的参数创建一个 UnsafeBufferPointer<T> (如在原始代码中) - 即 UnsafeRawBufferPointer.

我会直接使用建议的替换,即 withUnsafeBytes(_:),其第一个参数是 UnsafeRawBufferPointer,而不是不必要地构建数组或复制缓冲区,例如:

static func extractPacketSizeFromIV(iv: Data) -> Int32? {
    return iv.withUnsafeBytes { rawBuffer -> Int32 in
        let buffer = rawBuffer.bindMemory(to: Int32.self)
        let r0 = buffer[0].bigEndian
        let r1 = buffer[1].bigEndian
        let r2 = buffer[2].bigEndian

        return r2 ^ r1 ^ r0
    }
}

显然,如果您的 Data 比这更复杂(例如,具有许多不同类型和不同大小的异构负载),可能需要不同的方法,但如果这是一个简单的缓冲区,只有Int32 的简单集合,以上是检索必要值的有效方法。