在Swift 3中,如何从Data获取UnsafeRawPointer?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Swift 3中,如何从Data获取UnsafeRawPointer?相关的知识,希望对你有一定的参考价值。

根据Swift 3中Data的文档,我可以使用一个初始化程序从UnsafeRawPointer创建数据。实际上我需要的是相反的。我有一个数据,我想创建一个指向数据字节的UnsafeRawPointer。这就是我现在正在做的事情:

1. let data = <from some where>
2. let unsafePointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
3. unsafePointer.initialize(to: 0, count: data.count) // is this necessary?
4. data.copyBytes(to: unsafePointer, count: data.count)
5. let unsafeRawPointer = unsafePointer.deinitialize() // this is of the type UnsafeMutalbleRawPointer, and I can use it where UnsafeRawPointer is needed.

我确认此代码适用于Xcode Playground。代码甚至可以在没有行号3的情况下工作。我不确定有没有线路的区别。无论如何,我的问题是,我做得对吗?有更简单的方法吗?

答案

withUnsafeBytes()为您提供了一个指向字节的(类型)指针,可以将其转换为原始指针:

let data = <Data from somewhere>
data.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in
    let rawPtr = UnsafeRawPointer(u8Ptr)
    // ... use `rawPtr` ...
}

指针仅在对闭包调用的生命周期内有效。

或者,您可以桥接到NSData并访问原始字节:

let nsData = data as NSData
let rawPtr = nsData.bytes

现在指针在nsData有效的相同范围内有效。

从Swift 5开始

let data = <Data from somewhere>
data.withUnsafeBytes { rawBufferPointer in
    let rawPtr = rawBufferPointer.baseAddress!
    // ... use `rawPtr` ...
}

因为封闭论证现在是UnsafeRawBufferPointer

另一答案

检查the latest reference

我们找不到从UnsafeRawPointer检索Data的方法或属性。

因此,替代方案:func withUnsafeBytes((UnsafePointer) -> ResultType)

你可以写这样的东西:

let data: Data = <initialize it as you like>

data.withUnsafeBytes {(uint8Ptr: UnsafePointer<UInt8>) in
    let rawPtr = UnsafeRawPointer(uint8Ptr)
    //`rawPtr` (and `uint8Ptr`) is guaranteed to be valid in this closure
    //...
    //You have no need manage `rawPtr`.
}

(哦,这与Martin R的答案的前半部分相同。)


但是如果你想保持你的UnsafeRawPointer有效期比封闭期更长,你需要复制Data的内容:

例如:

let uint8Ptr = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
uint8Ptr.initialize(from: data) //<-copying the data
//You need to keep `uint8Ptr` and `data.count` for future management
let uint8PtrCount = data.count
//You can convert it to `UnsafeRawPointer`
let rawPtr = UnsafeRawPointer(uint8Ptr)
//Use `rawPtr` while `uint8Ptr` is valid
//...
//Deinitialize and deallocate the region
uint8Ptr.deinitialize(count: uint8PtrCount)
uint8Ptr.deallocate(capacity: uint8PtrCount)

(您可以将UnsafeMutableRawPointer作为deinitialize(count:)的返回值,但该区域处于未初始化状态,因此您不应该访问该区域。)

另一答案

在Swift 5中:

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

可能的解决方案是:

buffer.withUnsafeBytes{ (bufferRawBufferPointer) -> Void in

    let bufferPointer: UnsafePointer<UInt8> = bufferRawBufferPointer.baseAddress!.assumingMemoryBound(to: UInt8.self)
    let rawPtr = UnsafeRawPointer(bufferPointer)
    //USE THE rawPtr

}

以上是关于在Swift 3中,如何从Data获取UnsafeRawPointer?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用swift 3仅获取Core Data中的一列数据

如何在 swift 3 中解析 JSON

如何在 Documents 文件夹中保存 UIImagePicker 中的 UIImage 并获取路径字符串以保存在 Swift 中的 Core Data 中

如何从 Swift 3 中的数据中读取属性列表

如何在swift 3中从字典中获取数组

使用 Swift 从 Core Data 中获取数据并在 UITextFields 中显示