Memory management in Swift

Memory management in Swift is done by Automatic Reference Counting or ARC. Whenever a variables holds an instance of an object the memory count for that object increases by 1. And when variable becomes out of scope or set to nil, the memory count decreases 1.

class Teacher {
    var name: String?
    var course: String?

    init (name: String, course: String) {
        self.name = name
        self.course = course
        print("Reference count increased by 1")
    }

    deinit{
        print("Reference count decreased by 1")
    }
}

let teacher1 = Teacher(name: "Ravi", course: "Swift")

func createTeacher() {
    let teacher2 = Teacher(name: "John", course: "Java")
}

createTeacher()

In the above example, we are creating two instances of Teacher class and storing it in variables teacher1 and teacher2. Since teacher2 variable is created within the function, it becomes out of scope after the function call. You should be able to observe the two init messages and one deinit (teacher2) message in console log. This should give you some idea on how reference counting works in Swift.

Increasing and decreasing of reference count are automatically handled by ARC but problem occurs when we have a strong reference cycle. A strong reference cycle refers to cyclic relationship between the objects.

class Teacher {
    var name:String?
    var course:String?
    var student: Student?

    init(name: String, course:String) {
        self.name = name
        self.course = course

        print("Reference count of Teacher increases by 1")
    }

    deinit {
        print("Reference count of Teacher decreases by 1")
    }
}

class Student {
    var name:String?
    var mentor: Teacher?

    init(name: String, course:String) {
        self.name = name

        print("Reference count of Student increases by 1")
    }

    deinit {
        print("Reference count of Student decreases by 1")
    }
}

func createInstance() {
    let teacher = Teacher(name: "Jason", course: "Swift")
    let student = Student(name: "Adam", course: "Swift")
    teacher.student = student
    student.mentor = teacher
}

createInstance()

In the above code snippet, Teacher and Student classes have a strong reference cycle and both student and teacher instances remain in memory even after the end of function call. A strong reference cycle can be avoided by declaring any one of the instance as weak or unowned

weak var student: Student?

You can also unown the reference when you know the reference cannot be nil

unowned var mentor: Teacher

unowned var mentor: Teacher

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.