Swift 数据转换为 UInt64

Swift Data convert to UInt64

我阅读了一些 Apple 文档,但我无法在对象中执行此操作。我通过蓝牙在 Data 类型的变量中接收一个 unix 时间戳值,我不想将它转换为 UInt64 var 来填充 UIDatePicker 但我实现的函数给了我错误: "Fatal error: UnsafeRawBufferPointer.load out of bounds"

你有什么建议吗?我正在使用 Swift 5.1

这是我的代码:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var datePicker: UIDatePicker!

    private func setDate(value: Data) {
        let date = Date(timeIntervalSince1970: TimeInterval(value.uint64))
        datePicker.setDate(date, animated: true)
    }
}

extension Data {
    var uint64: UInt64 {
        withUnsafeBytes { [=12=].load(as: UInt64.self) }
    }
}

当数据中没有足够的字节来形成 UInt64(少于 8 个)时,我会收到该错误。很有可能就是这里的情况。

解决此问题的一种方法是更改​​ uint64 以便它处理字节不足的情况。当字节不够时,它可以用0填充数据直到足够:

extension Data {
  var uint64: UInt64 {
        get {
            if count >= 8 {
                return self.withUnsafeBytes { [=10=].load(as: UInt64.self) }
            } else {
                return (self + Data(repeating: 0, count: 8 - count)).uint64
            }
        }
    }
}

这是假设小端设备和小端数据。如果数据是大端:

extension Data {
  var uint64: UInt64 {
        get {
            if count >= 8 {
                return self.withUnsafeBytes { [=11=].load(as: UInt64.self).bigEndian }
            } else {
                return (Data(repeating: 0, count: 8 - count) + self).uint64
            }
        }
    }
}

或者,如果可以的话,在您的蓝牙设备上解决这个问题,让它始终发送 8 个字节。

如果你知道你的蓝牙设备只会发送小端四字节值,那显然只有 32 位。我不确定为什么你会尝试从你知道只是 UInt32(或其他一些 32 位类型)的东西中提取 UInt64。所以我建议:

extension Data {
    var uint32: UInt32 { 
        withUnsafeBytes { [=10=].load(as: UInt32.self) }
    }
}

或者您可以使字节顺序明确:

extension Data {
    var uint32: UInt32 { 
        withUnsafeBytes { [=11=].load(as: UInt32.self).littleEndian }
    }
}