Middle
What is unowned in Swift and how is it used?
sobes.tech AI
Answer from AI
Unowned reference (weak indirect ownership) in Swift is used to avoid strong reference cycles (retain cycles), where two objects strongly reference each other, preventing their deallocation from memory.
Features of unowned:
- Guarantees that the object referenced by the
unownedreference always exists at the moment of access. - If you try to access an
unownedreference after the related object has been deallocated, a runtime crash will occur. - Used when the lifecycle of the referencing object is not longer than the lifecycle of the object it references. That is, an
unownedreference does not make the object stronger.
Example of usage in capturing closures:
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 to Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Card #\(number) is being deinitialized")
}
}
var john: Customer? // Optional Customer for deallocation
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// Setting john to nil will deallocate Customer and Card,
// since there is no strong reference cycle
john = nil
Another example - using unowned in a closure capture list:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [unowned self] in // Using unowned self
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")
}
}
var paragraph: HTMLElement? // Optional HTML element
paragraph = HTMLElement(name: "p", text: "hello world")
print(paragraph!.asHTML())
// Setting paragraph to nil will deallocate HTMLElement, as the closure does not strongly hold it
paragraph = nil
Choosing between unowned and weak depends on whether the reference can be nil during the object's lifetime. If the reference can never become nil before the object is deallocated, use unowned. If it can, use weak.