Skip to content
tezvyn:

Swift Closures: Functions with a Memory

MediumHow cards are made

A closure is a function carrying luggage: it captures surrounding variables and remembers them later. Use them in SwiftUI actions, async completions, and array transforms. Beware a strong reference cycle from capturing self without a capture list.

Why it exists

Functions sometimes need to run long after the context that created them has disappeared. If a function could only use its own parameters and global variables, every asynchronous callback would need cumbersome manual state passing. Closures solve this by letting a function bundle up the local variables it needs and take them along for later execution.

The mental model

Think of a closure as a function with a backpack. Inside the backpack are copies or references to variables from the place where the function was created. When the function is called later, maybe inside a network completion handler or a SwiftUI animation, it opens that backpack and accesses those captured values as if the original scope still existed.

How it works

In Swift, a closure is a self-contained block of functionality that can be passed around and used in your code. When a closure references a variable or constant from its surrounding scope, Swift captures it. For value types like Int or String, Swift captures a copy. For reference types like classes, Swift captures a reference to the instance, which means the closure shares ownership unless you specify otherwise. You control capture behavior with a capture list written in square brackets before the parameter list, such as [weak self] or [unowned self].

When to use it

Use closures for short-lived operations that need context without the boilerplate of a dedicated class or function. Common examples include completion handlers for URLSession data tasks, SwiftUI view modifiers, trailing closure syntax with array operations like sorted or filter, and escaping closures that outlive the function they are passed to.

When not to use it

Do not use a closure when the logic is complex enough to need multiple methods or stored properties; a dedicated struct or class is clearer. Avoid overly long trailing closures that force readers to scroll to understand what the trailing brace belongs to. And never ignore capture lists when self is referenced inside an escaping closure, because the default strong capture will keep the object alive and create a memory leak.

One canonical example

A network manager fetches user data and returns it in a completion handler. Inside the view controller, you write a data task with a trailing closure that includes the capture list [weak self], then unwraps self, and calls updateUI. Without [weak self], the closure strongly captures the view controller, the network task strongly captures the closure, and the view controller cannot deallocate until the network call finishes or the app terminates. Adding [weak self] breaks that cycle and lets memory management behave correctly.

Interview question

You reference self inside an escaping closure stored by a network task. Without a capture list, what memory issue arises?

  • a.The compiler raises an error because self requires explicit capture semantics
  • b.The closure and self keep each other alive, preventing deallocationCorrect
  • c.Swift copies self into the closure, so UI updates use a stale instance
  • d.The network task cancels automatically when the view controller is dismissed
Why?

The closure strongly captures self and the network task strongly captures the closure, creating a retain cycle that prevents deallocation until the task finishes or the app terminates. Option C confuses value-type capture with reference-type capture; classes are referenced, not copied.

Just read this? Test yourself on what you have been reading.

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.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.

See open roles