2

在观看了使用 value type 构建更好的应用程序之后。在他们制作的 Photoshop 示例中,他们说

在该图表的两个实例中唯一被复制的是包含该人衬衫的瓷砖。因此,即使我有两个不同的文档,旧状态和新状态,但我必须使用的唯一新数据是此人衬衫中包含的瓷砖。

所以我开始想知道这两个数组在内存中的样子。所以我做了一个小实验。

struct Test {
    var i: Int
    var j: Int
}

var valueArray = [Test(i: 1, j: 9), Test(i: 2, j: 7)]
var valueArray2 = valueArray

当我打印 valueArray 和 valueArray2 的地址时,它们是不一样的。
“也许他们通过在数组中存储指针来实现这一点?”
但是当我使用 lldb 打印内存内容时,它们实际上只是 4 Int (1,9,2,7)。
所以我很困惑,我什至还没有改变数组。他们似乎复制了整个数组?那我哪里误会了?
我用来打印结构地址的函数是使用@nschum 在这个问题中提供的方法。

func address(o: UnsafePointer<Void>) {
    let addr = unsafeBitCast(o, Int.self)
    print(NSString(format: "%p", addr))
}

这不是这个问题的重复问题。我在问语言羽毛,另一个是关于编程技能。

4

2 回答 2

2

好的,我做了很多实验,终于弄明白了。

  1. 我们可以使用&获取数组地址,因为一旦这样做,Swift 将复制数组以更好地与 C 交互,使用&获取与数组相邻的对象的地址并进行数学运算。或者使用 lldb 指令frame variable -L
  2. 一旦它的任何值元素发生更改,整个数组就会被复制。
  3. Array 的实际值元素在堆上分配。
  4. Swift 还对元素为 class 的 Array 做了很多优化。
  5. 斯威夫特很棒。

我实际上为此写了我的第一个博客

于 2016-04-10T05:00:51.223 回答
0

在您发表评论并更好地理解这一点之后,我将它加载到操场上,它似乎按预期工作

在此处输入图像描述

原始答案供参考

要记住的是,结构基本上是内存中的数据块。当您创建 valueArray 时,一块内存被设置为其分配的值

当您创建 valueArray2 时,您正在创建该结构的一个新实例,这意味着它将拥有一个全新的内存块,然后您将该新内存块的设置为与来自 valueArray 的内存。这会在两个不同的内存位置生成数据副本。

这与对象相反,在这种情况下 valueArray 将是指向一块内存的指针,而当您创建 valueArray2 时,它将创建一个指向同一块内存的新指针。

于 2016-04-08T04:12:48.483 回答