← All topics/Swift language features

Practical interview questions

Scenario-style prompts with sample answer outlines. Focus is on how you would design and reason in real codebases.

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 heap-allocated class instances; when the count hits zero, deinit runs. Structs are not ARC-managed as whole values, but nested class references inside structs still participate in ARC.

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 referent outlives the reference — access after deallocation crashes. Only use it when the lifetime relationship is guaranteed.

Closures capture strongly by default. Use [weak self] or [unowned self]; capture lists appear before the closure’s parameter list.

Principles

  • Prefer weak over unownedunowned crashes if the referent is deallocated while still referenced.
  • Delegate properties must be weak; a strong delegate creates a retain cycle.
  • Escaping closures capture self strongly — add [weak self] whenever the closure may outlive its owner.
  • Timers, notification observers, and network callbacks are classic retain cycle sources.
Weak delegate pattern
protocol DetailDelegate: AnyObject {
    func onDone()
}

final class DetailVC {
    weak var delegate: DetailDelegate?
}
Closure capture
fetch { [weak self] result in
    guard let self else { return }
    self.apply(result)
}

Follow-up angles

  • @MainActor does not remove ARC concerns—escaping closures still need weak self where cycles are possible.