Retain cycles and how to break them
ARC and closure capture.
a cycle is two objects (or a closure and its owner) holding mutual strong references so neither deallocates; break it with a [weak] or [unowned] capture list.
What's really being asked
It verifies you understand Automatic Reference Counting and can spot and break the closure-capture cycles that dominate real iOS memory bugs.
What a retain cycle is
ARC frees an object when its strong reference count hits zero. A retain cycle forms when objects, directly or through a closure, hold strong references to each other so neither count ever reaches zero. The memory is unreachable but never freed, a leak. The classic case is an object that stores a closure while that closure strongly captures the same object via self.
How to resolve it
Use a capture list to make the closure's capture of self non-strong. [weak self] makes self an Optional that becomes nil once the object deallocates, so you safely unwrap before use; choose it when the closure may outlive self or self may legitimately disappear. [unowned self] assumes self always outlives the closure and accesses it without optionality; choose it only when that lifetime guarantee truly holds, because a stale unowned access crashes.
The mistakes people make
Defaulting to unowned for convenience where the object can deallocate first, inviting crashes. Believing every closure leaks, when non-escaping closures and closures that do not capture self are fine. Adding [weak self] without then handling the nil case.
What usually comes next
When is unowned safe over weak? Do non-escaping closures cause cycles? How do delegates create cycles and why are they weak? How do you confirm the fix with the Memory Graph Debugger?
A concrete example
A class stores a completion handler: self.onDone = { self.update() }. Here self retains the closure and the closure retains self, so the object never deallocates. Rewriting it as self.onDone = { [weak self] in self?.update() } breaks the strong link; once nothing else holds the object it deallocates, the weak reference goes nil, and the update simply no-ops.
Interview question
When breaking a closure retain cycle, when is [unowned self] the wrong choice compared to [weak self]?
- a.Whenever the closure is non-escaping
- b.Only when self is a struct rather than a class
- c.When self could deallocate before the closure runs, since an unowned access would then crashCorrect
- d.Never; unowned is always safer than weak
Why? this is the answer
unowned assumes self outlives the closure; if self can deallocate first, accessing it crashes, so weak is correct there. Non-escaping closures and value types are separate concerns.
Just read this? Test yourself on what you have been reading.
Read the original → docs.swift.org
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.
See open roles