0
0
Swiftprogramming~15 mins

Computed properties in Swift - Deep Dive

Choose your learning style9 modes available
Overview - Computed properties
What is it?
Computed properties in Swift are properties that do not store a value directly. Instead, they provide a getter and optionally a setter to calculate a value dynamically when accessed or modified. They look like regular properties but run code behind the scenes to produce or update their value. This allows properties to reflect changes in other data or perform calculations on demand.
Why it matters
Computed properties exist to keep data consistent and up-to-date without manually updating multiple values. Without them, programmers would need extra code to recalculate or synchronize related values, leading to bugs and harder maintenance. They make code cleaner and safer by centralizing logic for derived values, improving reliability and reducing errors in apps.
Where it fits
Before learning computed properties, you should understand basic Swift properties and variables. After mastering computed properties, you can explore property observers, lazy properties, and advanced Swift features like property wrappers and key paths. Computed properties build on the idea of encapsulating logic within properties.
Mental Model
Core Idea
A computed property acts like a window that shows a value calculated fresh every time you look through it, instead of a box that holds a fixed value.
Think of it like...
Imagine a thermostat that shows the current temperature by measuring it each time you check, rather than storing yesterday's temperature. The display updates dynamically based on real-time data, just like a computed property calculates its value on demand.
┌─────────────────────────────┐
│       Computed Property      │
├──────────────┬──────────────┤
│   Getter     │   Setter     │
│ (calculate)  │ (update)     │
└──────┬───────┴──────┬───────┘
       │              │
       ▼              ▼
┌─────────────┐  ┌─────────────┐
│  Other Data │  │  Other Data │
│  or State   │  │  or State   │
└─────────────┘  └─────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding stored properties
🤔
Concept: Learn what stored properties are and how they hold values directly in Swift.
In Swift, a stored property is a variable or constant that stores a value as part of an instance. For example: struct Person { var name: String // stored property var age: Int // stored property } Each Person instance keeps its own copy of name and age values.
Result
You can create a Person and access or change its stored properties directly.
Knowing stored properties is essential because computed properties build on the idea of properties but differ by not storing values directly.
2
FoundationIntroducing computed properties syntax
🤔
Concept: Learn how to write a computed property with getter and optional setter in Swift.
A computed property uses curly braces with get and set blocks instead of storing a value. Example: struct Rectangle { var width: Double var height: Double var area: Double { get { return width * height } } } Here, area is computed each time you access it.
Result
Accessing rectangle.area runs the get code and returns width times height.
Understanding the syntax lets you create properties that calculate values dynamically instead of storing them.
3
IntermediateComputed properties with setters
🤔Before reading on: do you think a computed property can change other properties when set? Commit to your answer.
Concept: Learn how to add a setter to a computed property to update other stored properties when assigned a value.
You can add a set block to a computed property to react when someone assigns a new value. Example: struct Rectangle { var width: Double var height: Double var area: Double { get { return width * height } set { width = newValue / height } } } Setting area changes width to keep the area consistent.
Result
Assigning rectangle.area = 50 updates rectangle.width accordingly.
Knowing setters let computed properties not only provide values but also control how related data changes, keeping state consistent.
4
IntermediateRead-only computed properties
🤔Before reading on: do you think a computed property can omit the setter if it only returns a value? Commit to your answer.
Concept: Learn that computed properties can be read-only by providing only a getter, simplifying syntax.
If a computed property only needs to return a value and never be set, you can omit the set block and even the get keyword: struct Circle { var radius: Double var diameter: Double { return radius * 2 } } This is a read-only computed property.
Result
Accessing circle.diameter returns radius times two, but you cannot assign to diameter.
Understanding read-only computed properties helps write cleaner code when only dynamic reading is needed.
5
IntermediateUsing computed properties for data consistency
🤔Before reading on: do you think computed properties can help avoid bugs from inconsistent data? Commit to your answer.
Concept: Learn how computed properties keep related data synchronized automatically.
Instead of storing redundant values, computed properties calculate values on demand, preventing mismatches. For example, a temperature converter: struct Temperature { var celsius: Double var fahrenheit: Double { get { return celsius * 9 / 5 + 32 } set { celsius = (newValue - 32) * 5 / 9 } } } Changing fahrenheit updates celsius and vice versa.
Result
Temperature values stay consistent without manual syncing.
Knowing computed properties enforce consistency reduces bugs and simplifies maintenance.
6
AdvancedPerformance considerations of computed properties
🤔Before reading on: do you think computed properties always run instantly like stored properties? Commit to your answer.
Concept: Learn that computed properties run code each time accessed, which can affect performance if expensive.
Because computed properties execute code on every access, complex calculations or heavy operations can slow your app. For example, a computed property that reads a file or performs a long calculation should be used carefully or cached. struct DataLoader { var data: String { // Imagine reading a large file here return "Expensive data" } } Repeated access runs the code repeatedly.
Result
Performance may degrade if computed properties do heavy work without caching.
Understanding the cost of computed properties helps avoid slowdowns by choosing when to compute or store values.
7
ExpertComputed properties and property observers interaction
🤔Before reading on: do you think property observers like willSet run on computed properties? Commit to your answer.
Concept: Learn that property observers do not work on computed properties and why.
Property observers (willSet, didSet) only work on stored properties because they monitor direct value changes. Computed properties run code instead of storing values, so observers cannot detect changes on them. struct Example { var stored: Int = 0 { willSet { print("Will set stored") } } var computed: Int { get { return stored * 2 } set { stored = newValue / 2 } } } Observers run only when stored changes directly, not when computed is set.
Result
Observers do not trigger on computed properties, which can surprise developers.
Knowing this prevents bugs where observers are expected but silently ignored on computed properties.
Under the Hood
Computed properties are implemented as methods behind the scenes. The getter and setter are compiled into functions that run when the property is accessed or assigned. The Swift compiler treats them like special methods but lets you use property syntax for readability. No actual storage is allocated for computed properties; instead, the code runs each time to produce or update values.
Why designed this way?
Swift designed computed properties to combine the clarity of property syntax with the flexibility of methods. This lets developers write clean, expressive code without losing control over how values are calculated or updated. Alternatives like separate methods would be more verbose and less intuitive. The design balances simplicity and power.
┌───────────────┐
│ Property Call │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│  Getter Code  │
│  or Setter    │
│  Function     │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│  Computation  │
│  or Update    │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do computed properties store values in memory like variables? Commit to yes or no.
Common Belief:Computed properties store values just like regular variables do.
Tap to reveal reality
Reality:Computed properties do not store values; they calculate or update values on demand through code.
Why it matters:Assuming computed properties store values can lead to unexpected bugs when values change dynamically or performance issues if expensive calculations are repeated.
Quick: Can property observers like willSet run on computed properties? Commit to yes or no.
Common Belief:Property observers work on all properties, including computed ones.
Tap to reveal reality
Reality:Property observers only work on stored properties, not computed properties.
Why it matters:Expecting observers on computed properties can cause silent failures in monitoring changes, leading to debugging headaches.
Quick: Does adding a setter to a computed property automatically store the new value? Commit to yes or no.
Common Belief:A setter in a computed property saves the new value automatically like a stored property.
Tap to reveal reality
Reality:The setter runs code you write; it does not store the value unless you explicitly update stored properties inside it.
Why it matters:Misunderstanding this causes bugs where values appear not to change because the setter does not update any stored data.
Quick: Are computed properties always fast to access? Commit to yes or no.
Common Belief:Computed properties are as fast as stored properties because they look like normal properties.
Tap to reveal reality
Reality:Computed properties run code every time they are accessed, which can be slow if the code is complex or resource-heavy.
Why it matters:Ignoring performance costs can cause slow apps or unexpected delays in user interfaces.
Expert Zone
1
Computed properties can be used with protocols to require dynamic calculations without specifying storage, enabling flexible API design.
2
When multiple computed properties depend on each other, careful design is needed to avoid infinite loops or inconsistent states.
3
Using computed properties with key paths allows powerful dynamic access and modification patterns in Swift.
When NOT to use
Avoid computed properties when the calculation is very expensive and accessed frequently; instead, use stored properties with caching or lazy properties. Also, do not use computed properties if you need property observers, as they only work with stored properties.
Production Patterns
Computed properties are widely used in SwiftUI to create dynamic views that update automatically based on state. They also appear in model objects to derive values like full names from first and last names, or to convert units on the fly, keeping data consistent and UI reactive.
Connections
Lazy properties
Related concept that delays computation until first use, unlike computed properties which run every access.
Understanding computed properties clarifies when to use lazy properties to optimize performance by computing once instead of on every access.
Functional programming
Computed properties embody the idea of pure functions that return values based on inputs without side effects.
Recognizing computed properties as functions helps appreciate immutability and stateless design principles from functional programming.
Thermostat control systems (Engineering)
Both compute outputs dynamically based on inputs to maintain consistency and respond to changes.
Seeing computed properties like a thermostat's dynamic temperature reading reveals how software mimics real-world control systems for reliability.
Common Pitfalls
#1Expecting a computed property setter to store a value automatically.
Wrong approach:struct Example { var value: Int { get { return 10 } set { /* no stored property updated */ } } } var e = Example() e.value = 20 print(e.value) // still prints 10
Correct approach:struct Example { private var _value: Int = 10 var value: Int { get { return _value } set { _value = newValue } } } var e = Example() e.value = 20 print(e.value) // prints 20
Root cause:Misunderstanding that setters must explicitly update stored data; computed properties do not store values themselves.
#2Adding property observers to computed properties expecting them to run.
Wrong approach:struct Example { var computed: Int { willSet { print("Will set") } // invalid get { return 5 } } }
Correct approach:struct Example { var stored: Int = 0 { willSet { print("Will set") } } var computed: Int { get { return stored * 2 } } }
Root cause:Confusing stored and computed properties; observers only apply to stored properties.
#3Using expensive operations inside computed properties without caching.
Wrong approach:struct Data { var largeData: [Int] = Array(0...1000000) var sum: Int { return largeData.reduce(0, +) // runs every access } }
Correct approach:struct Data { var largeData: [Int] = Array(0...1000000) lazy var sum: Int = { return largeData.reduce(0, +) // computed once }() }
Root cause:Not considering that computed properties run code every time, causing performance issues.
Key Takeaways
Computed properties calculate values dynamically each time they are accessed, unlike stored properties that hold fixed values.
They can have getters and setters to read and update related stored data, keeping values consistent automatically.
Computed properties do not store data themselves, so property observers do not work on them.
Because they run code on every access, expensive computations should be avoided or cached to maintain performance.
Understanding computed properties helps write cleaner, safer, and more maintainable Swift code by centralizing logic within properties.