将 NSData Objective-C 代码转换为 Swift 时遇到问题



我一直在将 Objective-C 代码片段转换为使用NSDataCoreBluetooth的 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
}

最新更新