Swift Automatic Reference Counting

In swift, Automatic Reference Counting (ARC) is used to perform memory management by releasing or cleaning unused class instances in an application. Generally, in swift we don’t need anything to release unused class instances, ARC will automatically free up the memory used by class instances that are no longer needed.

 

Generally in applications, we will create an instance for classes to access the defined methods and properties and after completion of using class instances, ARC automatically removes those instances and free the device memory. In swift, ARC will work only for reference types like classes, it won’t work for enumeration or structure type values.

 

In some cases, ARC required more information about our code to perform memory management effectively.

Functionality of ARC in Swift

The following are the important points that will describe how ARC will work to handle memory management.

 

  •  When we create an instance of a class, ARC will assign a block of memory to store the information about the instance. The information stored in memory will hold the type of instance, properties, and methods of an instance.
  • In case if the instance is no longer needed, ARC will free up the memory used by that instance so that memory can be used for other purposes.
  • If ARC deallocates an instance that is in use, the properties and methods of particular instance no longer available to access in the application.
  • ARC will keep a track on instance properties, methods or variables to know any of one active reference to that instance still exists or not based on that it will deallocate the instances.
  •  In swift when we assign a class instance to a property, constant or variable, that variable or constant makes a strong reference to that instance so the instances are not allowed to deallocate as long as the strong reference exists.

Now we will see how Automatic Reference Counting (ARC) will work in a swift programming language with examples.

 

Following is the example of defining a simple class “Student” with some stored properties to initialization and deinitialization process in a swift programming language.

 

class Student {

let fullname: String

init(name: String) {

self.fullname = name

print("\(name) is initialized")

}

deinit {

print("\(fullname) is deinitialized")

}

}

var ins: Student? =  Student(name: "Trishika Dasari")

ins = nil

If you observe above example we defined a class “Student” with initialization and deinitialization functionality. We defined a variable “ins” and assigned a Student class instance.

 

When we run the above program in swift playground we will get a result like as shown below

 

Trishika Dasari is initialized

Trishika Dasari is deinitialized

The statement ins = nil will assign a nil to an optional ins variable that means no instance of Calculate class.

Strong Reference Cycles between Class Instances

Strong reference is referred as an object which is not deallocated by ARC. A strong reference object is deallocated only when our application is completely exit. 

 

In swift, we can define class instances that can hold strong reference to each other and each instance keep the other instance alive so this is called a strong reference cycle in a swift programming language.

 

Following is the example of defining strong reference cycle in a swift programming language.

 

class Student {

var name: String

var teacher: Teacher?

init(name: String) {

print("\(name) is initialized")

self.name = name

}

deinit {

print("\(name) is deinitialized")

}

}

class Teacher {

let name: String

var student: Student?

init(name: String) {

print("\(name) is initialized")

self.name = name

}

deinit {

print("\(name) is deinitialized")

}

}

var stu: Student? =  Student(name: "Trishika Dasari")

var teach: Teacher? =  Teacher(name: "Suresh Dasari")

stu!.teacherteach

teach!.studentstu

If you observe above example the Student class has a strong reference in Teacher class and vice-versa. Both have a strong references with each other.

 

When we run the above program in swift playground we will get a result like as shown below

 

Trishika Dasari is initialized

Suresh Dasari is initialized

This is how the strong reference in a swift programming language to keep class instances are active.

 

In swift, we have two ways to resolve strong reference cycles those are

 

  • Weak References
  • Unowned References

The weak and unowned references enable one reference in a reference cycle refer to the other instance without keeping a strong hold on it. The instances can refer to another instance without creating a strong reference cycle.

 

In swift, we can use weak reference when another instance has a shorter lifespan that means other instance can deallocate first and unowned referenced can be used when other instances have the same lifespan or longer lifespan.

Swift Weak References in ARC

In swift weak reference is a reference that does not hold a strong reference to the instance that refers to memory. There is a possibility that instance can be deallocated from the memory due to weak references and ARC can dispose the deallocated reference instance from the memory even though weak references still referring to it.

 

In swift, we can define a weak reference by placing a weak keyword just before a property or variable declaration.

 

The ARC will set a weak reference to nil when an instance that is referring is deallocated from the memory. In swift there is a chance of changing the weak reference values to nil during runtime, so always we need to define reference instances as variables not with constants or optional types.

 

Following is the example of defining a weak reference in a swift programming language.

 

class Student {

var name: String

var teacher: Teacher?

init(name: String) {

self.name = name

}

deinit {

print("\(name) is deinitialized")

}

}

class Teacher {

let name: String

weak var student: Student?

init(name: String) {

self.name = name

}

deinit {

print("\(name) is deinitialized")

}

}

var stu: Student?

var teach : Teacher?

stu = Student(name: "Trishika Dasari")

teach = Teacher(name: "Suresh Dasari")

stu!.teacherteach

teach!.studentstu

stu = nil

teach = nil

If you observe above example we defined a two classes Student, Teacher. Here Student instance is a strong reference to Teacher instance but Teacher instance is not a strong reference to the Student instance because we defined a weak reference in Teacher class using weak keyword.

 

When we run the above example in swift playground we will get a result like as shown below

 

Trishika Dasari is deinitialized

Suresh Dasari is deinitialized

This is how we can use weak references in a swift programming language to maintain weak relations between instances based on our requirements.

Swift Unowned References in ARC

In swift unowned references are same as weak references, it won’t keep a stronghold on the instance it refers to but unowned references are useful when other instances have a same or longer life span. We can define an unowned reference by placing an unowned keyword just before a property or variable declaration.

 

In swift, ARC will never set an unowned reference value to nil, which means always unowned references must have a value and we need to define an unowned reference by using nonoptional types.

 

In swift, we can use unowned references only when we are sure that the reference always refers to an instance that has not been unallocated. In case if we try to access an unowned reference value after the instance deallocated, we will get a runtime error.

 

Following is the example of defining an unowned reference in a swift programming language.

 

class Student {

var name: String

var teacher: Teacher?

init(name: String) {

self.name = name

}

deinit {

print("\(name) is deinitialized")

}

}

class Teacher {

let name: String

unowned let student: Student

init(name: String, student: Student) {

self.name = name

self.student = student

}

deinit {

print("\(name) is deinitialized")

}

}

var stu: Student?

stu = Student(name: "Trishika Dasari")

stu!.teacherTeacher(name: "Suresh Dasari", student: stu!)

stu = nil

If you observe above example we defined a two classes Student, Teacher. Here Student instance is a strong reference to Teacher instance but Teacher instance has an unowned reference to the Student instance because we defined a unowned reference in Teacher class using unowned keyword.

 

When we run the above example in swift playground we will get a result like as shown below

 

Trishika Dasari is deinitialized

Suresh Dasari is deinitialized

This is how we can use unowned references in a swift programming language to make sure instance references are not deallocated by ARC based on our requirements.

Swift Strong Reference Cycles for Closures

When we declare multiple strong instances of multiple classes that refer to each other. Here, the actual problem is how we can create a cycle between two strong references. For this situation, we use weak and unowned references to connect the strong references of two classes. It only occurs when we assign an instance to a closure.

 

Following is the example of creating a strong reference cycle by using a closure in a swift programming language.

 

class Contact {

var name : String

var stext : String?

lazy var Details:() -> String = {

if let stext = self.stext {

return "Name: \(self.name), Text: \(stext)"

}

else {

return "Name: \(self.name)"

}

}

init (name: String, stext: String? = nil){

self.name = name

self.stext = stext

}

deinit {

print("\(name) is deinitialized")

}

}

var result : Contact? = Contact(name: "Suresh Dasari", stext: "Welcome to Tutlane")

print(result!.Details())

When we run above program in swift playground we will get result like as shown below

 

Name: Suresh Dasari, Text: Welcome to Tutlane

This is how we can use Automatic Reference Counting (ARC) in a swift programming language to deallocate class instances manually based on our requirements.