2017-08-15 3 views
2

私はセグを通ってデータを渡すときに奇妙なことに気がつきました。なぜこのようになるのか分かりません。私は、クラスの性質について何かを誤解している可能性が高いことを理解しています。その知識を得るための助けを得ることができれば幸いです。Swift - 渡されたカスタムクラスは、以前のビューに戻ったときに変更されたプロパティを保持するのはなぜですか?

segue(両方ともナビゲーションコントローラに接続されている)を介して2番目のビューにIntまたはStringを渡した後、2番目のビューでその値を変更してから、最初の値に戻すと、IntまたはStringは、最初のビューで最初に設定されたものと同じで、2番目のビューで変更された値は保持されません。これは理にかなっており、とにかく私が期待していることです。

しかし、カスタムクラスで作業しているときに気付きましたが、これは当てはまりません。そのクラスに属する値を変更した場合、最初のビューに戻るときに保持されます。私は、完全なクラスを完全に新しいものに置き換えようとすると、Intを全体的に変更しようとするのと似ているだろうが、クラスのプロパティを変更するだけで、その場合でも動作するのはなぜですか?

私は以前のビューにデータを戻す方法を知っていますが、これ以上理解できます。なぜがこのように機能しますか?

最初のビューコントローラ:

class ViewController: UIViewController { 

    var number = 5 
    var string = "Hello from View 1" 
    var object = Object(number: 5, string: "Hello from View 1", bool: false) 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     print("PAGE 1 NUMBER: ", number) 
     print("PAGE 1 STRING: ", string) 
     print("PAGE 1 OBJECT NUMBER: ", object.number) 
     print("PAGE 1 OBJECT STRING: ", object.string) 
     print("PAGE 1 OBJECT BOOL: ", object.bool) 
    } 

    @IBAction func buttonPress(_ sender: Any) { 
     self.performSegue(withIdentifier: "toSecond", sender: self) 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if segue.identifier == "toSecond" { 
      let vc = segue.destination as! SecondViewController 
      vc.number = number 
      vc.string = string 
      vc.object = object 
     } 
    } 
} 

第二ビューコントローラ:

私はここにそれで遊んでとしてきたが、より良い私が話しているかを説明するためのコードです

class SecondViewController: UIViewController { 

    var number = 0 
    var string = "" 
    var object = Object() 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     print("PAGE 2 NUMBER: ", number) 
     print("PAGE 2 STRING: ", string) 
     print("PAGE 2 OBJECT NUMBER: ", object.number) 
     print("PAGE 2 OBJECT STRING: ", object.string) 
     print("PAGE 2 OBJECT BOOL: ", object.bool) 

     number = 12 
     string = "Hello back from View 2" 

     object.number = 12 
     object.string = "Hello back from View 2" 
     object.bool = true 
     object = object2 
    } 
} 

コンソール出力:

PAGE 1 NUMBER: 5 
PAGE 1 STRING: Hello from View 1 
PAGE 1 OBJECT NUMBER: 5 
PAGE 1 OBJECT STRING: Hello from View 1 
PAGE 1 OBJECT BOOL: false 
PAGE 2 NUMBER: 5 
PAGE 2 STRING: Hello from View 1 
PAGE 2 OBJECT NUMBER: 5 
PAGE 2 OBJECT STRING: Hello from View 1 
PAGE 2 OBJECT BOOL: false 
PAGE 1 NUMBER: 5 
PAGE 1 STRING: Hello from View 1 
PAGE 1 OBJECT NUMBER: 12 
PAGE 1 OBJECT STRING: Hello back from View 2 
PAGE 1 OBJECT BOOL: true 

これまでの回答は数日前から検索されています。

+1

ヒント:クラスは参照型です。 – rmaddy

+0

あなたはすぐにクラスと構造体を使うことで最大の利点を理解しました。驚くばかり! – adev

+0

あなたはポインターと非常によく似たものを使って遊んでいます。オブジェクトを作成するときには、アドレスを使って作業しています。非常に良い質問。 –

答えて

0

まだ誰もあなたの質問に答えていないので、ここで私の答えを追加します。

しかし、カスタムクラスで作業しているときに気付きましたが、これは当てはまりませんでした。 そのクラスに属する値を変更した場合、最初のビューに戻るときには が保持されます。私が気付いたのは、 を完全に新しいクラスに置き換えようとした場合、 はInt全体を変更しようとするのと似ていますが、なぜ はクラスのプロパティだけを変更するのでしょうか?その場合?

コメントに記載されているように、クラスは参照型であり、そのプロパティに設定した値は同じインスタンスを使用するすべての場所で使用できるためです。 IMO、これは迅速な構造体に対するクラスの大きな利点です。この動作が望ましくない場合は、Objectをstruct型に変更することを検討できます。あなたはSecondViewControllervar object = Object()を初期化しているにもかかわらず、あなたはprepareForSegueメソッド内vc.object = objectとしてViewControllerであなたのobjectインスタンスとそのインスタンスを交換する、あなたのケースで

、。これを行っているので、オブジェクトのプロパティに加えた変更は、前の画面に戻っても保持されます。

関連する問題