Copying in Swift

Alok Upadhyay
7 min readMar 25, 2018

--

Hey It’s my first post and yeah I did it!

We will cover-

  1. Copy
  2. Deep Copy
  3. Shallow Copy
  4. Deep Copy Of Reference Types
  5. Copy On Write (COW)

I am going to talk about copying objects in swift. Copying can be two ways — copy content and copy reference.

Copy Content is also known as Deep Copy. Deep Copy works with value types. For example Structure, Array, Dictionary, Set, String etc.

Copy Reference is also known as shallow Copy. shallow Copy works with reference types. For example Classes.

Note — How to create deep copies of reference types?
The default copy of reference types is shallow Copy. We can create deep copies of reference types also by confirming to NSCopying and implementing copy(with zone: NSZone? = nil) -> Any.

Example of Deep Copy:

//At first we need a value type. Lets take a structure.
/*A person structure with variables personName and personAge*/
struct Person{
var personName : String?
var personAge : Int?
}
//Lets use the Person struct //lets create person object
var personObj = Person()

//lets set person properties
personObj.personName = "Alok"
personObj.personAge = 18

//lets create a another person object and copy personObj to personObjAnother object.
var personObjAnother = personObj

//lets set personObjAnother properties
personObjAnother.personName = "Naitvik"
personObjAnother.personAge = 3

//lets print personObj
print(personObj.personName!) //prints "Alok"
print(personObj.personAge!) //prints 18

//lets print personObjAnother
print(personObjAnother.personName!) //prints "Naitvik"
print(personObjAnother.personAge!) //prints 3

In above example we see that when we make deep copies, source (personObj) and destination(personObjAnother) objects have their own copies. Changes made to the newly copied objects does not impact source object.

Why Deep Copies ?

Deep copies are less prone to race conditions and suits well in multithreaded environment. You are sure the object on which you are performing changes will impact only same object. It will not make any impact on the source object. This is one of the reason also why apple have made collection types (Array, Dictionary, Set) as value types in Swift (which are reference types in Objective C).

Example of Shallow Copy:

/*A personC class with variables personName and personAge*/
class PersonC{
var personName : String?
var personAge : Int?
}
//lets create person objectlet personObj = PersonC()//lets set person propertiespersonObj.personName = "Alok"personObj.personAge = 18//lets create a another person object and assign personObj.let personObjAnother = personObj//lets set personObjAnother propertiespersonObjAnother.personName = "Naitvik"personObjAnother.personAge = 3//lets print personObj
print(personObj.personName!) //prints "Naitvik"
print(personObj.personAge!) //prints 3

//lets print personObjAnother
print(personObjAnother.personName!) //prints "Naitvik"
print(personObjAnother.personAge!) //prints 3

In above example we see that when we make shallow copies, source (personObj) and destination(personObjAnother) objects have shared copies. Changes made to the newly copied objects does also impact source object.

Why Shallow Copies ?

Shallow copies are faster to create because sharing the reference only. The created copies does not entirely create new instance in memory instead only address/reference is copied.

Creating Deep Copies Of Reference Types

In iOS we can create deep copies of reference types also by confirming to NSCopying Protocol and by implementing copy(with zone: NSZone? = nil) -> Any.

Example of deep copies of reference types

/*A personD class with variables personName and personAge*/
/*We have to confirm NSCopying protocol and implement func copy(with zone: NSZone? = nil) -> Any*/
class PersonD : NSCopying{
var personName : String?
var personAge : Int?

func copy(with zone: NSZone? = nil) -> Any {
let copy = PersonD()
copy.personName = self.personName
copy.personAge = self.personAge
return copy
}
//lets create person object
let personObj = PersonD()

//lets set person properties
personObj.personName = "Alok"
personObj.personAge = 18

/*lets create a another person object and assign personObj.
we will use copy method now to perform deep copy.
we have to make sure PersonD confirms to NSCopying protocol
and implements func copy(with zone: NSZone? = nil) -> Any*/
let personObjAnother = personObj.copy() as! PersonD

//lets set personObjAnother properties
personObjAnother.personName = "Naitvik"
personObjAnother.personAge = 3

//lets print personObj
print(personObj.personName!) //prints "Alok"
print(personObj.personAge!) //prints 18

//lets print personObjAnother
print(personObjAnother.personName!) //prints "Naitvik"
print(personObjAnother.personAge!) //prints 3

In above example we see that when we make deep copies of reference types, source (personObj) and destination(personObjAnother) objects have their own copies. Changes made to the newly copied objects does not impact source object.

Copy On Write (COW)

From the above discussions did you think about why a new copy should be created if you don’t make any changes in resulting copy. Will not it create duplicate content? What will happen if your array have 50 elements? Will it create new array with 50 elements again when you will perform copy? Think man think :).

Yes, you are right. Copying should not create duplicate content, and a new copy should be created only if a change is performed in copied object. That is, be it deep copy or shallow copy, a new copy will not be created until you make a change in copied object.

Example of Copy On Write

Look at base address raw value of a which is some thing like…3920 “Alok”.

After assigning a to b let’s look at base address raw value of a and b both which is some thing like…3920 “Alok”. That is even after performing copies new copy have not been still made.

After changing string b to “Naitvik”, lets again look at base address raw value of a and b both which is different now. For a it’s ….3920, however for b it’s ….3925. New copy is only made after some change have been performed to the copied object.

So, copy on write is a mechanism in built to be saved from creating duplicate content in memory.

Hope you like it. That’s it for now.

Subscribe Youtube: https://bit.ly/2STjOF3

Sample code:

Google Drive https://drive.google.com/file/d/1gVfRn2oPyP7GHtlEGOgfLywVkOBGiyS9/view?usp=sharing

Bitbucket

https://bitbucket.org/alokupadhyay/repos/get/SwiftCopying.zip

Happy Coding :)

Below is the link to all tutorials.

Bluetooth low energy (BLE) integration with Flutter.

https://iosdose.com/ble-operations-in-flutter/

Flutter Google Map, Current Location, Marker, Polyline & Autocomplete

Flutter Google Map, Current Location & Marker

Basic RxSwift

RxSwift & MVVM design pattern

SwiftUI based News App

VIPER

Routing/presenting in VIPER architecture

Protocol Delegate Design Pattern

https://iosdose.com/creating-an-ios-app-using-protocol-delegate-design-pattern/

MVVM using Swift

Optionals & 6 ways to unwrap

Multiline UILabel

StackView

Instrumentation (Leak, Allocation)

BLE Using Swift

Swift Interview Questions & Answers

Coredata Basics

Simple Core Data App Using UITableView

Creating Singleton Core Data Class

https://iosdose.com/swift-4-core-data-part-3-creating-a-singleton-coredatamanager-class-refactoring-insert-update-delete-operation/

Core Data Test Cases

Website: https://tinyurl.com/y5m695rf

--

--