I've noticed something odd when passing data through a segue and I just can't figure out why it would be this way. I understand I'm most likely misunderstanding something about the nature of classes, so I would appreciate if I could get some help in getting some knowledge about it.
When I pass an Int or a String to a second view through a segue (both connected to a Navigation Controller), then change that value within the second view, and then return to the first one, the value of that Int or String will be the same as it was set initially on the first view, not retaining the value that was changed in the second view. This makes sense and is what I would expect to happen anyway.
But I noticed when working with a custom class this was not the case. If I changed values that belonged to that class, they would retain when going back to the first view. I did notice that if I tried to replace the whole class with a completely new one, that would not take, which would be similar to trying to change a whole Int, but why would only changing the class' properties still work in that case?
I do know how to pass data back to a previous view, this is more so I can get a better understanding why things work like this.
I've been playing around with it and here is the code to better explain what I'm talking about:
First View Controller:
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
}
}
}
Second View Controller:
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
}
}
Console Output:
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
I've searched for a couple days for the answer to this (if it has been answered previously I would appreciate a link).
Since noone has answered your question yet, I will add my answer here.
But I noticed when working with a custom class this was not the case. If I changed values that belonged to that class, they would retain when going back to the first view. I did notice that if I tried to replace the whole class with a completely new one, that would not take, which would be similar to trying to change a whole Int, but why would only changing the class' properties still work in that case?
The reason for this behavior is because as mentioned in comments, classes are reference types and hence any value which you set to its properties are available in all places where you use the same instance of it. IMO, this is a great advantage of classes against structs in swift. If you don't want this behavior you can consider changing Object
to a struct type.
In your case, even though you are initializing var object = Object()
in SecondViewController
, you are replacing that instance with your object
instance in ViewController
as vc.object = object
inside prepareForSegue
method. Since you are doing this, any change you make to object's property will be retained when you come back to previous screen.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments