Sobes.tech
Middle

What is unowned?

sobes.tech AI

Answer from AI

unowned is a keyword in Swift for declaring a weak reference. It is used when two objects have a strong relationship and their lifecycles depend on each other, but we want to avoid cyclic references that could prevent memory from being released.

Main properties and differences from weak:

  • Non-optional: An unowned reference is guaranteed not to be nil during the lifetime of the object it references.
  • Strong relationship: Used when one object owns another, and they always exist together.
  • On deallocation: If the object referenced by an unowned reference is deallocated before the reference is used, it will cause a runtime crash. It is necessary to ensure that the object referenced by an unowned reference exists longer than the reference itself.
  • Usage: Often used for delegates, where the delegate always exists longer than the object that calls it, or in closures to avoid cyclic references to self when the closure does not capture a strong reference to self.

Example of usage in a closure:

// swift
class MyClass {
    var name: String
    var closure: (() -> Void)?

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

    func setupClosure() {
        closure = { [unowned self] in // Using unowned self
            print("My name is \(self.name)")
        }
    }

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

Example of usage for a delegate (although weak is more commonly used for delegates, unowned is also possible if the delegate guaranteed lives longer):

// swift
protocol MyDelegate: AnyObject { // AnyObject requires a reference type
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned reference to delegate

    init(delegate: MyDelegate) {
        self.delegate = delegate
    }

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource deinitialized")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

    override init() {
        super.init()
        dataSource = DataSource(delegate: self)
    }

    func doSomething() {
        print("Delegate method called")
    }

    deinit {
        print("MyController deinitialized")
    }
}

The choice between weak and unowned depends on whether the reference is optional and whether the object it references is guaranteed to exist until the end of the reference's lifetime. If there is a possibility that the object may be deallocated before the reference is used, weak should be used. If there is a guarantee of existence and the reference should not be optional, unowned can be used.