If we look at the types in swift, there are two types — one is “Value Type” and the other is “Reference Type”.
Value Type- Each instance keeps a unique copy of data
Reference Type- Each instance shares a unique copy of data
In swift, Structure is Value Type, whereas Class is Reference Type.
Here person1 is copied as value type to person2. person1 and person2 have unique copies of data of their own. When we update the value of person2, it affects only person2, person1 remains unchanged.
Here person1 and person2 both instances share the same reference. As a result, If we change person2, it affects person1 also, and vice-versa.
So we see there are two types of object copying — Deep Copy and Shallow Copy
A deep copy is the value type of copy. When a structure is copied, it is deep type copy.
Deep Copy duplicates everything. With a deep copy, any object pointed to by the source is copied and the copy is pointed to by the destination.
In the case of a race condition and multi-thread issue, there is no worry about impacting other copy while changing in a copy. In a deep copy, there are multiple copies and there is no relation among the copies.
Deep Copy is slower than Shallow Copy.
With a shallow copy, any object pointed to by the source is also pointed to by the destination. So only one object will be created in the memory. A copy of a class object is a shallow copy.
Shallow copies are faster than deep copy, because of sharing the reference only. The created copy doesn’t entirely create a new instance in memory, just address/reference is copied.
As reference is shared, value change in a copy changes all the other. So in race condition and multi-thread issues, a shallow copy is risky.
Can we make a Deep Copy of Reference Type?
Yes, we can!
Make the class conforms to NSCopying protocol
From the documentation
A protocol that objects adopt to provide functional copies of themselves.
The exact meaning of “copy” can vary from class to class, but a copy must be a functionally independent object with values identical to the original at the time the copy was made. A copy produced with
NSCopying is implicitly retained by the sender, who is responsible for releasing it.
In the example, we have a class address, which is conformed to protocol NSCopying. We implemented the protocol method copy.
we have an object address1 and copy to address2. The copy is surely a reference type.
But in address3, we made a copy of that address1 object and changed the object variable city.
Surely, we see that, address3.city prints Mymensingh instead of Dhaka
So, it is clear both copies of address1 and address3 are different and they don’t share the same memory.
This is how we can make a deep copy of a reference type.