将 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 转换为使用 NSDataCoreBluetooth 的 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] 数组, 可以改用DatawithUnsafeBytes()方法。

如果没有,最后你可以返回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 并再次返回

NSArray怎么转换为NSData

如何将String转换成UInt8或NSData

将 NSData 转换为 NSString 并再次转换为 NSData?

将 GIF 图像转换为 nsdata