Swift - Why does a passed custom class retain changed properties when returning to previous view?

Shoegazing

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

adev

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.

edited at
0

Comments

0 comments
Login to comment

Related

UserDefaults does not store custom Swift Class properties

Why can't I access the Object's properties from another class? (even when the Object was passed to the class that is trying to access the properties)

table view cell of custom class returning nil

Why custom comparator functions are passed in Class or Struct?

custom class method returning nil Swift IOS

JSON post returning null when passed from view to controller

Why Does ExtJS do not Publish the activeItem value in the view model when the active tab is changed via mouse click?

NSKeyedUnarchiver returning nil when retrieving custom class

How does Haskell know to retain Nothing as nothing when passed to a lambda that returns Just x?

Custom UILabel class does not change properties?

Retain text in TabWidget when icons are changed

Why does the Cascade for CSS Custom Properties Not Work?

Why use a reference when returning an ostream class?

Opening a view from a custom class Swift IOS

Why css transition happens when CSS properties are not changed?

Why does custom WinForms control not adhere to properties set in constructor when drawn?

Why does Swift not allow stored properties in extensions?

Does android View reference passed to outside class create memory leak?

How to pass data to the previous view controller if it is the same class Swift

Why does my custom event's data not get passed?

How to set Notification if view size changed when using multitasking | Swift

onTextChange target not called when text is changed with picker view - iOS Swift

Swift: background color is changed when presenting view controller modally

When does a self retain a closure?

Why custom properties for IdentityUser custom class are always null

Setting label text in a UICollectionViewCell not working when string is passed to custom class

View does not update when changing RealmObject passed as binding

Why view.onLayout() is called repetitively when changed=false?

Why does mutt retain deleted emails in view until you "sync your mailbox" using $?