当前位置: 首页 > 面试题库 >

在Swift中将数据读入结构

邢博涛
2023-03-14
问题内容

我正在尝试使用该方法来简单地读Data入Swift 4 。问题struct``withUnsafeBytes

网络UDP数据包具有以下html" target="_blank">格式:

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,需要一个startlength个要读取的字节

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

我应该像这样解析整个结构吗?


问题答案:

从数据读取整个结构不起作用,因为struct成员被 填充 到其自然边界。的内存布局struct XPLBeacon

 AB xx CCCCDDDD

哪里

 抵消成员
  0 A-majorVersion(UInt8)
  1 B-minorVersion(UInt8)
  2 xx-填充
  4 CCCC-applicationHostId(UInt32)
  8 DDDD-版本号(UInt32)

并插入填充,以便将UInt32成员对齐到其大小倍数的内存地址。这也得到了证实

print(MemoryLayout<XPLBeacon>.size) // 12

(有关Swift中对齐的更多信息,请参见 Type
Layout
)。

如果将整个数据读入结构,则按以下方式分配字节

 01 02 0A 00 00 00 0B 00 00 00
 AB xx CCCCDDDD

这就解释了为什么major/minorVersion是正确的,但applicationHostIdversionNumber
是错误的。从数据中单独读取所有成员是正确的解决方案。



 类似资料:
  • 问题内容: 这个问题的解决方案不再适用于Swift 3。 不再有一个属性的(前身。 有了这段代码,我得到了错误: 你怎么能写一斯威夫特3? 问题答案: 具有访问字节的属性。Swift 3中的新值类型具有一个 方法,该方法调用带有指向字节的指针的闭包。 因此,这就是您写入的方式 (不强制转换为): 备注: 是通用方法: 在上述调用中,两者和都是由编译器自动推断的(as 和),从而无需进行其他 转换。

  • 问题内容: 这段代码曾经很好(在某种意义上,编译器没有抱怨): 从Swift 5.0开始,这会产生警告: 警告:不建议使用“ withUnsafeBytes”:请改用 我试着用所提出的方法,但我似乎无法缠斗到这最终需要。 如何以不推荐的方式编写此函数? 问题答案: 诀窍是使用函数: 尽管此功能适用于Swift 5.0,但显然存在一些问题。参见相关论坛讨论。

  • 我有一个带有MongoDB的Nodejs应用程序。现在我想使用Elasticsearch将数据从mongo复制到Elasticsearch。我正在使用npm软件包“ElasticSearch”。例如,对于收藏“帖子”,我有这样的: 正如您所看到的,我的数据是非结构化的,并且Elasticsearch在我添加这些项时显示了错误。我想要一个把戏关闭弹性搜索限制,允许我添加这些数据。我不能改变我的数据它

  • 问题内容: 如何在Swift中将用户的TextField输入限制为数字? 问题答案: 您可以使用的方法将用户的输入限制为数字: 为Swift 3更新:

  • 问题内容: 我一直在寻找答案,但只能找到答案。 我有一个按钮可以选择。没有代码,我通过“接口”构建器进行设置。上,我有一个按钮,可以自行关闭 我想从视图传递回时传递一个字符串。我该怎么做呢?另外,我正在使用swift。 提前致谢! 问题答案: 有两种常见的模式,这两种模式都消除了viewController2明确了解viewController1的需要(这对于可维护性非常重要): 为您的viewC

  • 问题内容: 我有一个想要完全适应我想要的应用程序 我一直在关注Seemu Apps的Youtube教程,但是我需要添加一个可选的ViewController来完成它 该应用程序有2个显示车辆的tableViews,如果我们单击第一个tableView的一行,则第二个tableView将向我们显示选定车辆的列表。 这是到目前为止我们所拥有的:(图像链接,因为我在stackOverFlow上没有十分的