Built-in property wrappers (@State, @Published) in Swift - Time & Space Complexity
When using built-in property wrappers like @State and @Published, it's important to understand how their updates affect program speed.
We want to know how the time to update or notify changes grows as the number of properties or observers increases.
Analyze the time complexity of updating a @Published property with multiple observers.
class Model: ObservableObject {
@Published var value: Int = 0
}
let model = Model()
// Simulate multiple observers
for _ in 1...n {
model.$value.sink { newValue in
print("Value changed to \(newValue)")
}
}
model.value = 10
This code sets up a @Published property and attaches n observers that react when the value changes.
Look for repeated actions that affect performance.
- Primary operation: Notifying each observer when the property changes.
- How many times: Once per observer, so n times for n observers.
As the number of observers (n) increases, the time to notify all observers grows linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 notifications |
| 100 | 100 notifications |
| 1000 | 1000 notifications |
Pattern observation: Doubling the number of observers doubles the notification work.
Time Complexity: O(n)
This means notifying observers takes time proportional to how many observers there are.
[X] Wrong: "Updating a @Published property is always fast and constant time regardless of observers."
[OK] Correct: Each observer must be notified, so more observers mean more work and longer update time.
Understanding how property wrappers notify observers helps you reason about app responsiveness and performance in real projects.
What if we changed from multiple observers to a single observer that updates multiple UI elements internally? How would the time complexity change?
Practice
@State property wrapper in SwiftUI?Solution
Step 1: Understand what
@Statedoes@Stateis used to keep simple, local data inside a SwiftUI view.Step 2: Recognize its effect on UI
When the@Statedata changes, SwiftUI automatically updates the view to reflect the new data.Final Answer:
To store local, simple data inside a view and update the UI when it changes -> Option CQuick Check:
@Statemanages local view data = B [OK]
- Confusing @State with @Published
- Thinking @State is for class properties
- Assuming @State handles network or async tasks
@Published property inside a Swift class?Solution
Step 1: Identify where
@Publishedcan be used@Publishedis used inside classes that conform toObservableObject, not structs.Step 2: Check syntax correctness
class MyClass { @Published var count: Int = 0 } correctly declares a class with a@Publishedproperty and initializes it.Final Answer:
class MyClass { @Published var count: Int = 0 } -> Option DQuick Check:
@Publishedused in classes = A [OK]
- Using @Published in structs
- Confusing @State with @Published
- Missing var keyword or initialization
class Counter: ObservableObject {
@Published var value = 0
}
struct ContentView: View {
@StateObject var counter = Counter()
var body: some View {
VStack {
Text("Count: \(counter.value)")
Button("Increment") {
counter.value += 1
}
}
}
}
What will be displayed after tapping the "Increment" button twice?Solution
Step 1: Understand the initial state
TheCounterclass starts withvalue = 0. The view shows "Count: 0" initially.Step 2: Analyze button action and updates
Each tap on "Increment" increasescounter.valueby 1. After two taps, value becomes 2, and the UI updates automatically.Final Answer:
Count: 2 -> Option BQuick Check:
2 increments update value to 2 [OK]
- Forgetting @Published triggers UI update
- Assuming @StateObject resets value
- Counting taps incorrectly
class Model: ObservableObject {
@Published var text: String
init() {}
}
struct ViewContent: View {
@StateObject var model = Model()
var body: some View {
Text(model.text)
}
}Solution
Step 1: Check property initialization
The@Publishedpropertytextis declared but not initialized, and the init() is empty.Step 2: Understand Swift requirement for properties
All non-optional properties must have an initial value or be initialized in the constructor. Here,textlacks both.Final Answer:
Missing initial value for @Published property 'text' in Model -> Option AQuick Check:
Uninitialized property causes error = A [OK]
- Assuming @StateObject can't be used with ObservableObject
- Thinking Text can't display String
- Believing Model must be a struct
Solution
Step 1: Understand data sharing between views
When multiple views need to share and update data, use an ObservableObject class with@Publishedproperties.Step 2: Use
The main view can use@Statefor local view data and@Publishedfor shared data@Statefor local state, but the shared user name should be in a class marked with@Publishedto notify changes.Final Answer:
Use@Statein the main view and@Publishedin a shared ObservableObject class -> Option AQuick Check:
Shared data uses @Published; local uses @State [OK]
- Using @State only for shared data
- Using @Published in structs or views directly
- Not using ObservableObject for shared data
Ready to prove it?
Pass the test and this pattern moves unknown
