对于Swift 5转换缓冲指针,这些内存函数是否相同

对于Swift 5转换缓冲指针,这些内存函数是否相同,swift,generics,unsafe-pointers,unsafemutablepointer,Swift,Generics,Unsafe Pointers,Unsafemutablepointer,我正在对我不太理解的代码进行Swift 5转换,这些代码是以前开发人员的遗留代码。我得到: “withUnsafeBytes”已弃用:改用withUnsafeBytes(:(UnsafeRawBufferPointer)抛出->R)再抛出->R` 用于: 首先,您的toArray是在数据的扩展中定义的,对吗 (写问题时请澄清这些事情。) 在您的用例中,您的代码的工作方式与先前开发人员的代码相同,但我会在Swift 5中编写类似的代码,如下所示: func toArray<T>(typ

我正在对我不太理解的代码进行Swift 5转换,这些代码是以前开发人员的遗留代码。我得到:

“withUnsafeBytes”已弃用:改用withUnsafeBytes(:(UnsafeRawBufferPointer)抛出->R)再抛出->R`

用于:


首先,您的
toArray
是在
数据的扩展中定义的,对吗

(写问题时请澄清这些事情。)

在您的用例中,您的代码的工作方式与先前开发人员的代码相同,但我会在Swift 5中编写类似的代码,如下所示:

func toArray<T>(type: T.Type) -> [T] {
    return self.withUnsafeBytes {
        [T]($0.bindMemory(to: type))
    }
}
func-toArray(类型:T.type)->[T]{
返回self.withUnsafeBytes{
[T] ($0.bindMemory(收件人:类型))
}
}

bindMemory(to:type)
从new
with unsafebytes
传递的参数创建一个
UnsafeBufferPointer
(与原始代码一样),也就是说,

我会直接使用建议的替换,即其第一个参数是
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
    }
}

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

谢谢@Rob我添加了更多关于它们如何使用的信息。您的代码看起来像来自的Swift 4和Swift 5版本–您可以留下评论并要求澄清:)bindMemory的潜在问题是,它需要为绑定正确对齐内存类型,通常很难判断给定数据值的内存是如何对齐的。这就是为什么我建议在中使用copyMemory。是的,当然,但这个问题清楚地表明,
数据仅由这三/四个
Int32
值组成,因此我不会用
copyMemory
或您拥有的任何东西(特别是如果缓冲区是大型同质集合)来不必要地使这一点复杂化。当然,如果您有一个更复杂的
数据
,具有不同大小的异构数据类型,那么您可以将其升级到下一个级别,但不是在这里,IMHO。。。。如果基础内存与Int32值对齐。
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
}
func toArray<T>(type: T.Type) -> [T] {
    return self.withUnsafeBytes {
        [T]($0.bindMemory(to: type))
    }
}
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
    }
}