0
0
Swiftprogramming~5 mins

Unowned references for guaranteed lifetime in Swift

Choose your learning style9 modes available
Introduction

Unowned references let you refer to another object without keeping it alive, assuming it will always exist while you use it.

When two objects refer to each other but one always outlives the other.
To avoid memory leaks caused by strong reference cycles.
When you want to keep a reference without increasing the object's lifetime.
In delegate patterns where the delegate is guaranteed to exist while the delegator exists.
Syntax
Swift
class SomeClass {
    unowned var other: OtherClass

    init(other: OtherClass) {
        self.other = other
    }
}

An unowned reference must always point to an object that exists while you use it.

If the object is deallocated, accessing an unowned reference will cause a runtime crash.

Examples
A CreditCard has an unowned reference to its Customer because the card cannot exist without the customer.
Swift
class Customer {
    let name: String
    var card: CreditCard?

    init(name: String) {
        self.name = name
    }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer

    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
}
The Department has an unowned reference to Company because the company always exists while the department exists.
Swift
class Department {
    let name: String
    unowned let company: Company

    init(name: String, company: Company) {
        self.name = name
        self.company = company
    }
}

class Company {
    let name: String
    var department: Department?

    init(name: String) {
        self.name = name
    }
}
Sample Program

This example shows a Person and an Apartment. The apartment has an unowned reference to the person because the person always exists while the apartment exists. When john is set to nil, both objects are deinitialized without a memory leak.

Swift
class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
    }

    deinit {
        print("Person \(name) is being deinitialized")
    }
}

class Apartment {
    let unit: String
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
    }

    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person? = Person(name: "John")
john!.apartment = Apartment(unit: "4B", tenant: john!)

john = nil
OutputSuccess
Important Notes

Use unowned only when you are sure the referenced object will not be nil during the reference's lifetime.

If the referenced object might become nil, use weak instead to avoid crashes.

Accessing an unowned reference after the object is deallocated causes a runtime error.

Summary

Unowned references let you refer to another object without increasing its lifetime.

They are used when the referenced object is guaranteed to exist while you use it.

Using unowned helps avoid memory leaks from strong reference cycles.