Swift 中 MemoryLayout.size 中数组的大小

Posted

技术标签:

【中文标题】Swift 中 MemoryLayout.size 中数组的大小【英文标题】:Size of arrays in MemoryLayout.size in Swift 【发布时间】:2020-06-10 12:11:48 【问题描述】:

对不起,如果问题可能重复,我在这里找不到,也无法使用谷歌。

我是不安全的 Swift 新手,我想知道为什么布尔数组的大小(例如 10 个字节)仍然是 8 个字节?

如果我不能说出我的意思,我想知道你是否可以看看这段代码:

var boolArray = [Bool]()
for _ in 1...10
    boolArray.append(true)

print(MemoryLayout.size(ofValue: boolArray))

我不明白为什么它打印 8 而数组有 10 个至少包含 10 个字节的布尔值。

【问题讨论】:

无关但有用:您可以将数组生成缩短为 Array(repeating: true, count: 10) 或者如果您正在处理类并想要 10 个不同的对象:(1...10).map _ in YourClass() @LeoDabus 你是最好的一种权利 - 技术上正确 @ParsaNoori 从技术上讲,您甚至不能在现代 CPU 上加载比缓存行少的任何东西。但是您仍然可以访问成分。虽然您不能单独加载单个位,但您可以加载整个字节,屏蔽除您要查找的位之外的所有位,然后读取它。 @ParsaNoori 由于每个字节有 8 位,您可以使用索引的最后 3 位以外的所有位来选择要查看的字节,并使用最后 3 位来编码你感兴趣的位。例如,如果您想要索引 59 处的Bool(二进制中的0b111011),则查看第 7 个字节(0b111)。假设那个字节的值是0b11111111(全是“真”)。我们关心位 3 (0b011),所以我们通过与掩码 0b00000100 进行与运算来掩码 0b1111111。结果是0b00000100,表示设置了第3位。 @ParsaNoori 如果该字节的值为0b11111011,在用0b00000100 屏蔽后,我们将得到0x00000000,这意味着第3 位已关闭。 【参考方案1】:

这是因为 Array 本身并不真正存储任何东西 - 在内部,它们持有对堆分配内存的引用,它真正存储数据。

这样做的原因之一是优化 - 它允许使用写时复制机制。 Arraystruct,因此它是一个值类型。但是,不需要每次复制Array时都复制它所保存的数据——相反,多个Arrays可以指向同一个内存区域,只要它们不修改即可。

【讨论】:

有理由猜测代表“Array容器”的数据结构是 8 个字节长。这是一个只对语言设计者感兴趣的不透明结构。 @MikeRobinson 相反,它的内部工作令人着迷,并且可能会引起许多从未接触过语言设计的人(包括我自己)的极大兴趣。【参考方案2】:

因为函数大小的结果不包括任何动态分配或离线存储。见https://developer.apple.com/documentation/swift/memorylayout/2486283-size

【讨论】:

以上是关于Swift 中 MemoryLayout.size 中数组的大小的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Swift 3 项目中使用 Swift 2.3 框架吗?

swift中数组操作

iOS开发中OC和swift的对比

将 Swift 3 升级到 4,目标 c 中不再有 swift 扩展

在 Swift 项目中使用 Objective C 类中的 Swift 类

在 Swift 项目中使用 Objective C 类中的 Swift 类