2

値 type を使用してより良いアプリを構築するのを見た後。彼らが作ったPhotoshopの例では、彼らは言った

その図の 2 つのインスタンスでコピーされるのは、人物のシャツを含むタイルだけです。したがって、古い状態と新しい状態という 2 つの別個のドキュメントがありますが、結果として消費しなければならなかった唯一の新しいデータは、この人のシャツに含まれるタイルです。

それで、メモリ内のこれら 2 つの配列がどのように見えるか疑問に思い始めました。そこで、ちょっとした実験をします。

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))
}

これは、この質問の重複した質問ではありません。私は言語フェザーについて、もう 1 つはプログラミング スキルについて質問しています。

4

2 に答える 2

2

さて、私は多くの実験を行い、最終的に理解しました。

  1. 配列アドレスを取得するために使用でき&ます。これを行うと、Swift は配列をコピーして C との対話を改善し、配列に&隣接する get オブジェクトのアドレスを使用して代わりに計算を行います。またはlldb命令を使用しますframe variable -L
  2. 値要素のいずれかが変更されると、配列全体がコピーされます。
  3. 配列の実際の値要素はヒープに割り当てられます。
  4. Swift は、要素がクラスである Array に対しても多くの最適化を行いました。
  5. スイフトはすごい。

私は実際にこれのために私の最初のブログを書きます。

于 2016-04-10T05:00:51.223 に答える
0

あなたのコメントとこれについての理解を深めた後、プレイグラウンドにロードしましたが、期待どおりに機能しているようです

ここに画像の説明を入力

参考までに元の回答

ここで覚えておくべきことは、構造体は基本的にメモリ内のデータの塊であるということです。valueArray を作成すると、メモリのチャンクが割り当てられた値に設定されます

valueArray2 を作成すると、構造体の新しいインスタンスが作成されます。つまり、新しいメモリ チャンクが作成され、その新しいメモリ チャンクの、 valueArray からのメモリ。これにより、2 つの異なるメモリ位置にデータのコピーが作成されます。

これはオブジェクトの場合とは対照的です。この場合、valueArray はメモリのチャンクへのポインターであり、valueArray2 を作成すると、同じメモリのチャンクへの新しいポインターが作成されます。

于 2016-04-08T04:12:48.483 に答える