Sobes.tech
Middle

What is the difference between Wick references and Anound references?

sobes.tech AI

Answer from AI

Wick reference (weak) — is a non-owning reference. It does not increase the reference count of the object. It is used to prevent strong reference cycles, for example, between a delegate and its owner. If the object pointed to by a weak reference is deallocated, the weak reference automatically becomes nil.

Unowned reference (unowned) — is also a non-owning reference and does not increase the reference count of the object. The difference from weak is that unowned cannot be an optional and must always point to an existing object. If the object pointed to by an unowned reference is deallocated before the reference is accessed, attempting to access this reference will result in a runtime error (fatal error). It is used where the lifecycle of the related object is guaranteed to be longer or equal to the lifecycle of the object with the unowned reference (for example, in a strong reference cycle where one object has a clearly defined lifecycle).

Comparison:

Feature weak unowned
Non-owning Yes Yes
Increases SC No No
Can be nil Yes (automatically nilled) No (must point to an object)
Safety Safer in case of deallocation Less safe (fatal error on access to deallocated object)
Type Must be optional Cannot be optional (by default)
Usage Preventing strong reference cycles where the object may cease to exist earlier Preventing strong reference cycles where the object is guaranteed to exist

Example of using weak to prevent a strong reference cycle:

class Person {
    let name: String
    weak var apartment: Apartment? // weak reference to avoid retain cycle

    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }

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

class Apartment {
    let unit: String
    var occupant: Person?

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) is being initialized")
    }

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

Example of using unowned in the context of capturing self in a closure:

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        [unowned self] in // unowned self to avoid retain cycle with closure
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}
What is the difference between Wick references and… - sobes.tech