Shallow copy and Deep copy in Swift
My colleague sometimes asks me why he just changes the object in his screen, but when back to previous screen, that object keeps the change. I tried to explain to him, then he wants me to write that into a small blog and share with others in the company.
Value type and Reference type
Value type — each instance keeps a unique copy of its data. A type that creates a new instance (copy) when assigned to a variable or constant, or when passed to a function. This type is stored in Stack memory.
Reference type — each instances share a single copy of the data. A type that once initialized, when assigned to a variable or constant, or when passed to a function, returns a reference to the same existing instance. This type is stored in Heap memory.
The most compared represents are Struct and Class
Struct is value type, it stores all variable values.
Class is reference type, it stores the address of object in heap memory (0x600000355a00).
Shallow copy
That copy is the default and only for reference type. (just use = syntax)
If we use that copy, it only assigns the address of object to the new object. And when the new object is changed, that means its value stored in heap memory will also be changed.
And when we get the value of old object, the fact that we are reading its value from heap memory, and now the value is changed!
Why we use shallow copy?
It is fast to create because not having to create new instance in memory, just passing the address. And the most important is that you do not need to write any extra code ;)
But when using it, please keep in mind that you are not only using a personal property, don’t put your teammate into trouble.
So how can I just change my own object? Let’s read more.
Deep copy
As mentioned below, the value type instance keeps a unique copy of its data. So when using = syntax, it will pass all values to new object. Then the change in new object will not affect to old object.
But with reference type, the story becomes more complex.
The simple idea is creating new instance (with another address in heap memory) and pass all value from old object to new object.
But I’m too lazy to sit down and assign each property while my class has 100 properties. Are there any automatic ways?
Let’s think about another idea. We will try to convert all object value into one thing that can pass automatically.
The key is JSON Encode/Decode. And thank for Apple, we had Codable from Swift 4.
The step will be:
- Create new object (difference address, of course)
- Encode old object into JSON data
- Decode that JSON data and assign to new object
Well! Now we had an automatic way, just 3 lines function and easy to use.