【发布时间】:2018-05-11 13:50:10
【问题描述】:
我正在尝试使用withUnsafeBytes 方法将裸Data 读入Swift 4 struct。问题
网络UDP数据包格式如下:
data: 0102 0A00 0000 0B00 0000
01 : 1 byte : majorVersion (decimal 01)
02 : 1 byte : minorVersion (decimal 02)
0A00 0000 : 4 bytes: applicationHostId (decimal 10)
0B00 0000 : 4 bytes: versionNumber (decimal 11)
然后我在Data 上有一个扩展,它需要start 和length 字节来读取
extension Data {
func scanValue<T>(start: Int, length: Int) -> T {
return self.subdata(in: start..<start+length).withUnsafeBytes { $0.pointee }
}
}
这在逐个读取值时可以正常工作:
// correctly read as decimal "1"
let majorVersion: UInt8 = data.scanValue(start: 0, length: 1)
// correctly read as decimal "2"
let minorVersion: UInt8 = data.scanValue(start: 1, length: 1)
// correctly read as decimal "10"
let applicationHostId: UInt32 = data.scanValue(start: 2, length: 4)
// correctly read as decimal "11"
let versionNumber: UInt32 = data.scanValue(start: 6, length: 4)
然后我创建了一个struct,代表整个数据包如下
struct XPLBeacon {
var majorVersion: UInt8 // 1 Byte
var minorVersion: UInt8 // 1 Byte
var applicationHostId: UInt32 // 4 Bytes
var versionNumber: UInt32 // 4 Bytes
}
但是当我将数据直接读入结构时,我遇到了一些问题:
var beacon: XPLBeacon = data.scanValue(start: 0, length: data.count)
// correctly read as decimal "1"
beacon.majorVersion
// correctly read as decimal "2"
beacon.minorVersion
// not correctly read
beacon.applicationHostId
// not correctly read
beacon.versionNumber
我应该像这样解析整个结构吗?
【问题讨论】:
-
请注意,您不需要在方法签名中传递长度。您可以只使用泛型类型的大小
func scanValue<T>(start: Int) -> T { return subdata(in: start..<start+MemoryLayout<T>.size).withUnsafeBytes { $0.pointee } } -
并将命名
start改为at
标签: swift