Value vs. Reference Semantics in Swift
Value types are like emailing a document copy; changes don't affect the original. Reference types are like a shared Google Doc link; everyone edits the same instance. In Swift, `structs` are copies, while `classes` are shared references.
WHY IT EXISTS To control how data is shared and mutated in a program. Sometimes you need a unique, safe copy of data that can't be changed unexpectedly from elsewhere. Other times, you need multiple parts of an app to coordinate by working on a single, shared piece of information. Swift provides both models to solve these distinct problems.
THE MENTAL MODEL Think of sharing a document. A value type is like emailing a file; your friend gets their own copy to edit, and their changes don't affect your original document. A reference type is like sending a link to a Google Doc; any change your friend makes is visible to you immediately because you are both looking at the exact same document in the cloud.
HOW IT WORKS When you assign a value type (like a struct or enum) to a new variable, Swift creates a full copy of the data. The new variable holds an entirely independent instance. When you assign a reference type (like a class), Swift only copies the reference—think of it as the memory address—not the data itself. Both the original and new variables now point to the exact same object in memory. Modifying the object through one variable is visible through the other because they share the one underlying instance.
WHEN TO USE IT Use value types (struct) by default for your data models in Swift. They make code easier to reason about because a variable's state won't be changed by another part of your program unexpectedly. This prevents an entire class of bugs related to shared mutable state. Use reference types (class) only when you specifically need shared state and a single source of truth, like for a network manager or a database connection that must be accessed from many places.
WHEN NOT TO USE IT Avoid using reference types (class) for simple data containers, like a model for a user profile or a settings object. This can lead to “action at a distance” bugs, where changing an object on one screen accidentally alters it on another. These bugs are notoriously difficult to track down because the cause and effect are far apart in the codebase.
ONE CANONICAL EXAMPLE Imagine a Document type. If it's a struct (value type), this code: var myDoc = Document(text: "Original"); var friendDoc = myDoc; friendDoc.text = "Edited"; leaves myDoc.text as "Original". The friendDoc is a separate copy. If Document is a class (reference type), the same code results in both variables pointing to the same object. Changing friendDoc.text to "Edited" also changes myDoc.text to "Edited", because there's only one shared document.
Read the original → swift.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.