What is the difference between strong, weak, unowned and unowned(unsafe)?
Predict first
What does this print?
final class Node {}
weak var w: Node?
do {
let n = Node()
w = n
print(w != nil)
}
print(w == nil)
- true, true
- true, false
- false, true
Predict first
Does this compile?
weak var count: Int?
- Yes
- No
Mental model. Strong is holding the rope. Weak is a note saying “the rope is over there, if it still exists”. Unowned is a note saying “the rope is definitely there”, and unsafe is a note nobody checks.
A strong reference keeps its target alive: it holds one count. The other three do not, and they differ in what you see after the target dies. A weak reference becomes nil automatically, so it must be an optional. An unowned reference is non-optional and promises the target is still there; reading it after death traps with a clear error. unowned(unsafe) makes the same promise with no safety net: reading it after death is undefined behaviour.
The costs follow. Weak needs runtime bookkeeping (a side table) and a check on every read. Unowned only needs a second, cheaper counter. Unsafe does nothing at all. Use weak for “might be gone”, unowned for “cannot be gone”, strong for ownership, and treat unowned(unsafe) as a last-resort optimisation.
While n is alive the weak reference sees it. When the do block ends the object dies and the weak reference is set to nil.
weak only applies to class types (and class-bound protocols). An Int is a value, so there is nothing to refer to weakly.
| strong | weak | unowned | unowned(unsafe) | |
|---|---|---|---|---|
| Keeps the target alive | yes | no | no | no |
| Type | any | Optional var | non-optional (or optional) | non-optional |
| After the target dies | cannot happen | becomes nil | traps when read | undefined behaviour |
| Runtime cost | retain / release | side table, atomic read | one extra counter | none |
Common traps
- Using
unownedto avoid writing the optional. You have swapped a harmlessnilfor a crash. - Making every back-reference strong. Two strong references pointing at each other form a cycle that ARC cannot free.
They might follow up with
- Which one needs a side table? Only weak. The next sections explain how.
- Can a struct property be weak? Yes, if its type is a class. The struct stores a weak reference to an object.
Related questions
- 3.2.2 Why is a weak reference optional, what can be weak, and what is the trap when reading one?
- 3.2.3 How do you decide between weak, unowned and strong for a back-reference?
- 3.4.4 What is a side table, and when does the runtime create one?
Why is a weak reference optional, what can be weak, and what is the… →