Explain ARC and how retain cycles happen.
Swift uses Automatic Reference Counting: each class instance has a reference count and is deallocated when the count reaches zero. ARC is deterministic, unlike a tracing garbage collector, but it only manages references, not cycles.
A retain cycle occurs when two objects strongly reference each other, so neither count reaches zero and memory leaks.
class Node {
var next: Node?
weak var parent: Node? // breaks the cycle
}
Break cycles with weak (optional, becomes nil when the target deallocates) for a child or back reference, or unowned (non-optional, assumes the target outlives the reference and traps otherwise). In closures use a capture list: [weak self] in self?.doWork(). Delegates should be declared weak var delegate.
Value types do not participate in cycles. Find leaks with Instruments' Leaks template and the memory graph debugger.