Home / iOS memory management interview questions
Swift language
iOS memory management interview questions
Memory management is a reliable iOS interview topic because it reveals whether you understand what the runtime is doing beneath your code.
What gets asked
Expect questions on Automatic Reference Counting, the difference between strong, weak, and unowned references, and how retain cycles form and break. A common exercise is spotting a cycle in a closure or delegate relationship and fixing it with a capture list. Follow-ups probe when to choose weak versus unowned and why delegates are usually weak.
Answering with confidence
Explain the mechanism, not just the rule. ARC releases an object when its strong reference count reaches zero; a cycle keeps that count above zero forever, so the memory is never reclaimed. Mention confirming a leak with the Xcode memory graph debugger or Instruments rather than guessing. That precision reads as senior.
How does ARC decide when to free an object?
The spoken answer: "ARC inserts retain and release calls at compile time. Every strong reference increments the count, every release decrements it, and the object is deallocated the moment the strong count hits zero. It is deterministic, not a garbage collector: there is no pause and no scanning, but it also cannot detect cycles." Two breaths, mechanism first.
The trap: "So ARC and garbage collection are basically the same thing?" Agreeing fails, because the difference is exactly why retain cycles exist. A tracing collector finds unreachable cycles; ARC never looks, so two objects holding each other strongly live forever. The recovery line: "Deterministic release is the benefit, cycle blindness is the cost, and weak references are how we pay it." The senior differentiator is noting that ARC applies to reference types only; a struct is not reference counted, but a struct holding a class reference still participates through that reference.
Find the retain cycle in this closure
The classic live exercise: a view controller stores a closure that reads self. The spoken answer: "self strongly retains the closure through the stored property, and the closure strongly captures self by default. That is a cycle, and neither deallocates. I break it with [weak self] in the capture list, then guard let inside so the body works with a strong local copy."
The trap: "Should every closure capture self weakly then?" Yes walks into it. A closure passed to a function that runs it and lets it go, like map or a UIView animation block, creates no cycle, and weak self there just adds noise and optional handling. In a Task doing work self should finish, a strong capture is often correct: it keeps self alive until the work completes. The recovery line: "Weak self is for closures that are stored, or escape into something self retains; short lived closures do not need it." The senior differentiator is describing the ownership arrows out loud: who retains the closure, who does the closure retain, and does that path loop back. Candidates who draw the arrows find cycles; candidates who sprinkle weak self by habit miss the one that matters.
When is unowned actually the right choice?
The spoken answer: "Unowned when the lifetime relationship is structural: the referencing object cannot outlive the referenced one, like a credit card object pointing back to the customer that owns it. It skips the optional and documents the invariant. If the invariant can break, weak."
The trap: "Unowned crashes, so is weak not always safer?" The obvious yes fails because it has no cost model. Weak turns a lifetime bug into a silent nil, and silent nils ship; unowned turns the same bug into a trap at the exact line the model broke. The recovery line: "Weak trades a loud crash for a quiet no-op, and quiet failures are the expensive ones." The senior differentiator is mentioning that weak references also carry runtime bookkeeping in a side table, so the choice has a small performance dimension, though correctness reasoning should decide it.
The 3 mistakes I see most in this round
- Reciting the weak versus unowned rule but failing to apply it to the delegate on the screen. The rule is the entry fee; applying it under time pressure is the score.
- Claiming a leak without evidence. The senior move is naming the tool: the memory graph debugger for the retain path, Instruments for allocations over time, and a deinit print as the quick check.
- Fixing the cycle and breaking the feature. [weak self] in the wrong place makes work silently stop when a screen closes. Interviewers notice when you check what should happen to in-flight work, not just whether the leak is gone.
Go deeper than a summary
Share Your Screen works topics like this through in full: 82 solved Swift problems with tests, 9 case studies (one real round, eight composites), and 7 annotated mock interviews, so you rehearse the live round instead of just reading about it.
Secure checkout on Gumroad. Instant PDF and EPUB download. Lifetime updates.
Frequently asked
What is the difference between weak and unowned?
Use weak when the reference may become nil during its lifetime; use unowned when the referenced object is guaranteed to outlive the reference, avoiding the optional.
How do you find a retain cycle?
Reproduce the leak, then use the Xcode memory graph debugger or Instruments Leaks to see which objects are retaining each other.