【问题标题】:Swift - converting from ConstUnsafePointer<()>Swift - 从 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 的解决方案看起来很有希望,当我有我的硬件时需要进行测试。

标签: ios swift


【解决方案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]")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多