我阅读了一些Apple文档,但我不能在对象中做这件事。我通过蓝牙在Data类型的变量中接收一个unix时间戳值,我不想将其转换为UInt64 var来填充UIDatePicker,但我实现的函数给我带来了错误:“致命错误:Un安全RawBufferPoint. 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) }
}
}
当数据中没有足够的字节来形成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
}
}
}
}
这是假设一个little-endian设备和little-endian数据。如果数据是大端:
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个字节。
如果您知道您的蓝牙设备只会发送小端四字节值,那显然只有32位。我不知道您为什么要尝试从您知道只是UInt32
(或其他32位类型)的东西中提取UInt64
。所以我建议:
extension Data {
var uint32: UInt32 {
withUnsafeBytes { $0.load(as: UInt32.self) }
}
}
或者你可以使endianness明确:
extension Data {
var uint32: UInt32 {
withUnsafeBytes { $0.load(as: UInt32.self).littleEndian }
}
}