0
0
Swiftprogramming~5 mins

Strong reference cycles between classes in Swift

Choose your learning style9 modes available
Introduction

Strong reference cycles happen when two class instances keep each other alive forever. This causes memory to not be freed, which can slow down or crash your app.

When two objects need to refer to each other, like a parent and child.
When you want to understand why your app uses too much memory.
When debugging why objects are not being removed from memory.
When designing classes that hold references to each other.
Syntax
Swift
class Person {
    var name: String
    var apartment: Apartment?
    init(name: String) { self.name = name }
}

class Apartment {
    var unit: String
    var tenant: Person?
    init(unit: String) { self.unit = unit }
}

Each class has a property that refers to the other class.

These references are strong by default, which can cause cycles.

Examples
Here, John and the apartment refer to each other strongly.
Swift
var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
Using weak breaks the strong cycle by making one reference weak.
Swift
class Person {
    var name: String
    weak var apartment: Apartment?
    init(name: String) { self.name = name }
}

class Apartment {
    var unit: String
    var tenant: Person?
    init(unit: String) { self.unit = unit }
}
Sample Program

This program creates two objects that refer to each other strongly. When we set both variables to nil, the objects are not deinitialized because of the strong reference cycle.

Swift
class Person {
    let name: String
    var apartment: Apartment?
    init(name: String) {
        self.name = name
        print("Person \(name) is initialized")
    }
    deinit {
        print("Person \(name) is being deinitialized")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person?
    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) is initialized")
    }
    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

john = nil
unit4A = nil
OutputSuccess
Important Notes

Strong reference cycles cause memory leaks because objects never get freed.

Use weak or unowned to break cycles.

Weak references must be optional because they can become nil.

Summary

Strong reference cycles happen when two objects keep strong references to each other.

This stops memory from being freed, causing leaks.

Use weak or unowned to avoid these cycles.