我一直在将 Objective-C 代码片段转换为使用NSData
和CoreBluetooth
的 Swift 时遇到问题。我已经研究了这个问题和其他几个在 Swift 中处理NSData
的问题,但没有任何成功。
Objective-C Snippet:
- (CGFloat) minTemperature
{
CGFloat result = NAN;
int16_t value = 0;
// characteristic is a CBCharacteristic
if (characteristic) {
[[characteristic value] getBytes:&value length:sizeof (value)];
result = (CGFloat)value / 10.0f;
}
return result;
}
到目前为止,我在 Swift 中拥有的内容(不起作用(:
func minTemperature() -> CGFloat {
let bytes = [UInt8](characteristic?.value)
let pointer = UnsafePointer<UInt8>(bytes)
let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 }
value = Int16(fPointer.pointee)
result = CGFloat(value / 10) // not correct value
return result
}
这里的逻辑看起来有问题吗?谢谢!
一个错误在
let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 }
因为反弹指针$0
仅在闭包内有效,并且必须 不传到外面。此外,容量应1
单个Int16
值。另一个问题是整数除法
result = CGFloat(value / 10)
这会截断结果(正如 the4kman 已经观察到的那样(。
不需要从数据创建[UInt8]
数组,而是 可以使用withUnsafeBytes()
Data
方法代替。
最后,如果没有,您可以返回nil
(而不是"不是数字"( 给出特征值:
func minTemperature() -> CGFloat? {
guard let value = characteristic?.value else {
return nil
}
let i16val = value.withUnsafeBytes { (ptr: UnsafePointer<Int16>) in
ptr.pointee
}
return CGFloat(i16val) / 10.0
}
您应该将返回值设置为可选,并在开头用guard
检查characteristic
是否为 nil 。您还应该将值显式转换为CGFloat
,然后将其除以 10。
func minTemperature() -> CGFloat? {
guard characteristic != nil else {
return nil
}
let bytes = [UInt8](characteristic!.value)
let pointer = UnsafePointer<UInt8>(bytes)
let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) { return $0 }
let value = Int16(fPointer.pointee)
result = CGFloat(value) / 10
return result
}