Search code examples
swiftclasspropertiespass-by-reference

Custom swift class properties passed by reference?


I have a custom class that I've written an equal/not equal function test for. I'm trying to test if an object I've modified is equal to the original object, but whenever I modify the second object, the original object seems to be modified as well. Here's some sample code (you can run this in a Playground):

// Custom class
class MyClass {
    var foo: Bool = false

    static func ==(a: MyClass, b: MyClass) -> Bool {
       return (a.foo == b.foo)
    }
    static func !=(a: MyClass, b: MyClass) -> Bool {
        return !(a==b)
    }

    required init() {
        // do nothing
    }
}

let originalObj: MyClass = MyClass()
var tempObj: MyClass = MyClass()

tempObj = originalObj

tempObj.foo = true

print(originalObj.foo) // Output: "true" (?!?!)
print(tempObj == originalObj) // Output: "true" (?!?!)

Why does changing the value of tempObj change the value of originalObj, and how can I prevent this behavior?


Solution

  • Classes in swift are Reference Types whereas Structs are Value Types. There are two ways to achieve what you want. You can either use struct instead of class or write a copy method for this class and use that method. Something like this

    class MyClass {
        var foo: Bool = false
    
        static func ==(a: MyClass, b: MyClass) -> Bool {
           return (a.foo == b.foo)
        }
        static func !=(a: MyClass, b: MyClass) -> Bool {
            return !(a==b)
        }
        required init() {
            // do nothing
        }
        func copy() -> MyClass {
            let temp = MyClass()
            temp.foo = foo
            return temp
        }
    }
    
    let originalObj: MyClass = MyClass()
    var tempObj: MyClass = originalObj.copy()