我读了一些苹果的文档,但我不能在目标上做这个事情。我正在通过蓝牙接收数据类型变量中的unix时间戳值,我不打算将其转换为UInt64变量来填充UIDatePicker,但我实现的函数给出了错误:“致命错误:超出界限的UnsafeRawBufferPointer.load”
你有什么建议吗?我用的是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 { $0.load(as: UInt64.self) }
}
}发布于 2020-04-03 17:34:27
如果您知道您的蓝牙设备只会发送小的endian 4字节值,那么显然只有32位。我不知道为什么要尝试从您知道的仅仅是一个UInt64 (或其他32位类型)的东西中提取一个UInt32。所以我建议:
extension Data {
var uint32: UInt32 {
withUnsafeBytes { $0.load(as: UInt32.self) }
}
}或者你也可以明确表示:
extension Data {
var uint32: UInt32 {
withUnsafeBytes { $0.load(as: UInt32.self).littleEndian }
}
}发布于 2020-04-03 16:26:28
当数据中没有足够的字节来形成UInt64 (小于8)时,我会得到这个错误。这里的情况很可能是这样。
解决这一问题的一种方法是更改uint64,以便在没有足够的字节时处理这种情况。当字节不足时,它只需使用0来填充数据,直到有足够的字节为止:
extension Data {
var uint64: UInt64 {
get {
if count >= 8 {
return self.withUnsafeBytes { $0.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 { $0.load(as: UInt64.self).bigEndian }
} else {
return (Data(repeating: 0, count: 8 - count) + self).uint64
}
}
}
}或者,如果可以的话,在你的蓝牙设备上解决这个问题,这样它总是发送8个字节。
https://stackoverflow.com/questions/61016007
复制相似问题