Swift - 从 ConstUnsafePointer<()> 转换

Posted

技术标签:

【中文标题】Swift - 从 ConstUnsafePointer<()> 转换【英文标题】:Swift - converting from ConstUnsafePointer<()> 【发布时间】:2014-07-11 00:44:49 【问题描述】:

我正在测试 3。请考虑以下 Objective-C 行:

const uint8_t *reportData = [data bytes];

其中dataNSData 对象。

如何用 Swift 重写这行代码?

data.bytesConstUnsafePointer&lt;()&gt; 类型,虽然有大量文档介绍如何在 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 3ConstUnsafePointer 需要更改为 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<()> 转换的主要内容,如果未能解决你的问题,请参考以下文章

从 swift 2.3 问题迁移到 swift 3.1

将代码从 Swift 2 更改为 swift 4

Alamofire - 从 Swift 2 转换为 Swift 3 时出错

从 Swift 2.3 迁移到 Swift 3 错误消息

从 Swift 2 转换为 Swift 3 时出错

项目在 Swift 中时无法从 Objective-C 访问 swift 类