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 }
}
}
我阅读了一些 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 }
}
}