Sobes.tech
Junior

What types of references exist in the Swift language?

sobes.tech AI

Answer from AI

In Swift, there are three main types of references:

  1. Strong Reference: The default type. Increases the reference count of the object. The object will not be deallocated from memory as long as there is at least one strong reference to it.

  2. Weak Reference: Does not increase the reference count. Marked with the keyword weak. Used to prevent strong reference cycles (retain cycles), where two objects strongly reference each other. A weak reference is an optional, as the object can be deallocated at any moment.

    // Example of Weak Reference
    class Person {
        let name: String
        weak var apartment: Apartment? // Weak reference
        init(name: String) { self.name = name }
        deinit { print("\(name) is being deinitialized") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Strong reference
        init(unit: String) { self.unit = unit }
        deinit { print("Apartment \(unit) is being deinitialized") }
    }
    
    var john: Person? = Person(name: "John Appleseed")
    var unit4A: Apartment? = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john
    
     john = nil // John is deallocated because Apartment.tenant does not hold a strong reference
    
  3. Unowned Reference: Does not increase the reference count, marked with the keyword unowned. Used when it is certain that the reference will always point to an object with a longer or equal lifetime. Unlike weak, an unowned reference is not an optional. Accessing the object through an unowned reference after its deallocation will cause a runtime error.

    // Example of Unowned Reference
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) { self.name = name }
        deinit { print("\(name) is being deinitialized") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Unowned reference
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Credit Card #\(number) is being deinitialized") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    john = nil // Both objects are deallocated
    

Brief comparison:

Reference Type Increases Retain Count Optional Runtime Check Usage
Strong Yes No No Default; used where full control over lifetime is needed
Weak No Yes Yes Prevents cycles; object can disappear
Unowned No No No (accessing nil causes error) Prevents cycles; used when sure the object exists
What types of references exist in the Swift language… - sobes.tech