RSS Feed ↗
VOL. 1 • NO. 14 • IOSBUFFET.COM OCT 25, 2026
Inside Page — A3 Continued from Front
The Daily Recipe
Sep 14, 2026 • Page A3

Instruments Finds the Leak Your Closures Hid

A detail screen that never deallocated, a retain cycle three closures deep, and the memory graph that exposed it.

By M. HOSSAIN — Staff Writer — Sep 14, 2026 340 words

The first symptom was a notification observer firing twice, then three times, then once more for every visit to a detail screen. The screen was being dismissed but never deallocated, and each zombie copy was still listening.

The fastest way to confirm a suspected leak is the Memory Graph Debugger. Run the app, visit the screen a few times, go back, and press the three-circle button in Xcode’s debug bar. Leaked instances show up in the navigator with a purple warning, and filtering by your class name shows exactly how many copies are alive.

Reading the graph

Selecting one of the zombie controllers showed the cycle: the controller owned a view model, the view model stored a completion closure, and that closure captured self — the controller — strongly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
final class RecipeDetailViewController: UIViewController {
    private let model = RecipeDetailModel()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Leaks: model -> closure -> self -> model
        model.onUpdate = { recipe in
            self.render(recipe)
        }

        // Fixed: the closure no longer keeps the controller alive
        model.onUpdate = { [weak self] recipe in
            self?.render(recipe)
        }
    }
}

Catching it next time

Instruments’ Leaks template will flag many cycles automatically, but the cheapest guard is a line in deinit during development — print("deinit \(Self.self)") — so a missing message is noticed immediately.

Two rules cover most cases. Closures that are stored by something you own need [weak self]. Closures that run once and are released, like UIView.animate blocks, don’t. When in doubt, check the graph.

— 30 —

— END OF EDITION 2026 — SET IN GARAMOND & COURIER ON NEWSPRINT STOCK — iOS BUFFET PRESS — RSS —