Swift - 从 ConstUnsafePointer<()> 转换
Posted
技术标签:
【中文标题】Swift - 从 ConstUnsafePointer<()> 转换【英文标题】:Swift - converting from ConstUnsafePointer<()> 【发布时间】:2014-07-11 00:44:49 【问题描述】:我正在测试 3。请考虑以下 Objective-C 行:
const uint8_t *reportData = [data bytes];
其中data
是NSData
对象。
如何用 Swift 重写这行代码?
data.bytes
是 ConstUnsafePointer<()>
类型,虽然有大量文档介绍如何在 Swift 中创建指针类型,但关于如何使用它们的信息并不多。
编辑: 为了添加一些上下文,我尝试将 Apple 的 HeartRateMonitor 示例代码移植到 Swift。此代码与 BLE 心率监视器交互。我正在处理的这段代码将蓝牙系统接收到的数据转换为 int 以在 UI 中使用。从 BT 接收到的数据应该是一个 uint 数组,元素 0 用于检查标志,元素 1 包含该值。
这是上下文中相同的 Objective-C 行:
const uint8_t *reportData = [data bytes];
uint16_t bpm = 0;
if ((reportData[0] & 0x01) == 0)
/* uint8 bpm */
bpm = reportData[1];
【问题讨论】:
你想用它做什么?你在 Objective-C 中做了什么?你试过做同样的事情吗?我的经验是,一切顺利。例如,单个“字节”应该可以使用下标访问。 在原始问题中添加了更多注释 你试过直接翻译吗?正如我之前所说,我的经验是,下标将按照您的预期工作。 没有发布我经历的每个排列,我会说我尝试了几个版本尝试“直接”翻译,或使用as
转换,或尝试通过一些其他指针对象。一些尝试由于类型原因无法编译,其他尝试会执行但会引发运行时异常。 dankogai 的解决方案看起来很有希望,当我有我的硬件时需要进行测试。
【参考方案1】:
您正在寻找的是如何将 NSData 转换为 UInt8 数组。方法如下。
import Foundation
let path = "/etc/csh.cshrc" // something existent
let data = NSData(contentsOfFile: path)
var aofb = [UInt8](count:data.length, repeatedValue:0)
data.getBytes(&aofb, length:data.length)
for c in aofb
let s = UnicodeScalar(Int(c)).escape(asASCII:true)
println("\(c):\(s)")
【讨论】:
刚刚为我的问题添加了更多上下文 - 收到的 NSData 对象实际上代表了一个 uint 数组,因此尝试转换为字符串是行不通的。 新示例展示了如何将 NSData 转换为 UInt8 的数组。【参考方案2】:刚刚构建了以下代码(注意以下代码适用于 Beta 3,ConstUnsafePointer 需要更改为 COpaquePointer要在 Beta 2 上工作,请查看编辑历史以了解更多信息)
var dataPath = NSBundle.mainBundle().pathForResource("TestData", ofType: "") // What I have in TestData is "GREETINGS WORLD"
var originalData = NSData(contentsOfFile: dataPath)
var dataLength = originalData.length
println("original data: \(originalData)") // Output original data
// Data to bytes
var reportBytes: ConstUnsafePointer<()> = originalData.bytes
var bytesToString = NSString(bytes: reportBytes, length: dataLength, encoding: NSUTF8StringEncoding)
println("string from bytes: \(bytesToString)")
// Bytes to data
var bytesToData = NSData(bytes: reportBytes, length: dataLength)
println("data from bytes: \(bytesToData)")
控制台日志
original data: <47524545 54494e47 5320574f 524c44>
string from bytes: GREETINGS WORLD
data from bytes: <47524545 54494e47 5320574f 524c44>
还发现这可能会有所帮助
ConstUnsafePointer<T>
/// This type stores a pointer to an object of type T. It provides no
/// automated memory management, and therefore the user must take care
/// to allocate and free memory appropriately.
希望这能有所启发。
【讨论】:
刚刚为我的问题添加了更多上下文 - 收到的 NSData 对象实际上代表了一个 uint 数组,因此尝试转换为字符串是行不通的。【参考方案3】:现在查看如何在 Swift 中处理蓝牙心率监视器,我发现了将 NSData 字节值转换为 UInt8 格式的最简单方法:
let bytes = UnsafePointer<UInt8>(data.bytes)
if bytes[0] & 0x01 == 0
NSLog("BPM \(bytes[1]")
【讨论】:
以上是关于Swift - 从 ConstUnsafePointer<()> 转换的主要内容,如果未能解决你的问题,请参考以下文章