Question 4
Memory management: ARC, strong, weak, unowned
Explain ARC's role in Swift. When do you use weak vs unowned references, and how do you break retain cycles in closures and delegates?
Answer outline
ARC counts strong references to class instances on the heap, and when the count hits zero, deinit runs. A struct itself isn't reference counted, but any class reference stored inside it still is.
weak is optional and becomes nil when the object is deallocated. Use it for delegates and closure captures where the referenced object may be released before the reference is used.
unowned is non-optional and assumes the object it points to outlives the reference. Accessing it after deallocation crashes, so only use it when that lifetime relationship is guaranteed.
Closures capture strongly by default, so when self stores a closure that uses self, the two keep each other alive. Break the cycle with [weak self] or [unowned self] in a capture list, which goes before the closure's parameter list.
Principles
- Prefer
weakoverunowned, becauseunownedcrashes if the object is already gone when you use it. - Delegate properties must be
weak, since a strong delegate creates a retain cycle. - Escaping closures capture
selfstrongly, so add[weak self]whenever the closure may outlive its owner. - Timers, notification observers, and network callbacks are the classic sources of retain cycles.
protocol DetailDelegate: AnyObject {
func onDone()
}
final class DetailViewController {
weak var delegate: DetailDelegate?
}
fetch { [weak self] result in
guard let self else { return }
self.apply(result)
}
Follow-up angles
@MainActordoesn't remove ARC concerns. Escaping closures still need[weak self]wherever a cycle is possible.



