Strong & Weak References in Swift
Written by Team Kodeco
In Swift, references to objects can be either strong or weak.
- A strong reference means that an object will not be deallocated as long as at least one strong reference to it exists.
- A weak reference, on the other hand, doesn’t prevent an object from being deallocated. When an object has only weak references, it’ll be deallocated.
Here is an example of how to use strong and weak references in Swift:
class Child {
var name: String
weak var parent: Parent?
init(name: String, parent: Parent) {
self.name = name
self.parent = parent
}
deinit {
print("Child \(name) is being deinitialized")
}
}
class Parent {
var name: String
var children: [Child] = []
init(name: String) {
self.name = name
}
func addChild(name: String) {
let child = Child(name: name, parent: self)
children.append(child)
}
deinit {
print("Parent \(name) is being deinitialized")
}
}
var parent: Parent? = Parent(name: "Sandy")
parent!.addChild(name: "Patrick")
parent!.addChild(name: "Emily")
parent!.addChild(name: "Joanna")
parent = nil
// Output: Parent Sandy is being deinitialized
// Child Patrick is being deinitialized
// Child Emily is being deinitialized
// Child Joanna is being deinitialized
In this example, You have two classes: Child
and Parent
.
- Each
Child
object has a weak reference to its parent, represented by theweak var parent: Parent?
property. - Each
Parent
object has a strong reference to its children, represented by thevar children: [Child]
property.
When the parent variable is set to nil
, the only remaining refererence to the parent variable is the references from its children, but those are weak, so ARC knows it’s safe to deallocate the parent.
Once the parent is deallocated, there are no longer any references to the children, so ARC can then deallocate them as well.
Beware of Retain Cycles
Consider what would have happened if weak var parent: Parent?
wasn’t set to weak
(and it was a strong reference instead).
In this case, when the parent variable is set to nil
, the Parent
object won’t be deallocated, because its children
still have a strong reference to it.
This would cause a strong reference cycle, also known as a retain cycle, where both the Parent
and Child
objects will never be deallocated, and it’ll cause memory leak.