将 NSData Objective-C 代码转换为 Swift 时遇到问题
Posted
技术标签:
【中文标题】将 NSData Objective-C 代码转换为 Swift 时遇到问题【英文标题】:Trouble converting NSData Objective-C code to Swift 【发布时间】:2017-07-24 18:22:16 【问题描述】:我在将 Objective-C sn-p 转换为使用 NSData
和 CoreBluetooth
的 Swift 时遇到问题。我看过this question 和其他几个在Swift 中处理NSData
的人,但没有取得任何成功。
Objective-C 片段:
- (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
这里的逻辑看起来有问题吗?谢谢!
【问题讨论】:
【参考方案1】:一个错误是在
let fPointer = pointer.withMemoryRebound(to: Int16.self, capacity: 2) return $0
因为反弹指针$0
只在闭包内部有效,必须
不能传到外面。此外,容量应为1
单个Int16
值。另一个问题是整数除法
result = CGFloat(value / 10)
它会截断结果(就像 observed by the4kman 一样)。
不需要从数据创建[UInt8]
数组,
可以改用Data
的withUnsafeBytes()
方法。
如果没有,最后你可以返回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
【讨论】:
【参考方案2】:您应该将返回值设为可选,并检查characteristic
是否以guard
开头。您还应该将该值显式转换为 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
【讨论】:
铸造值 likes 会给出错误“无法使用类型为 '(_)' 的参数列表调用类型为 'CGFloat' 的初始化程序”以上是关于将 NSData Objective-C 代码转换为 Swift 时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章
将 Objective-C malloc 转换为 Swift
使用正确的类型将 NSValue 转换为 NSData 并再次返回