WrappedValue and projectedValue in Swift - Time & Space Complexity
We want to understand how the time it takes to access and use wrappedValue and projectedValue changes as the program runs.
Specifically, how does the cost grow when these properties are used in Swift property wrappers?
Analyze the time complexity of accessing wrappedValue and projectedValue in this property wrapper example.
@propertyWrapper
struct Wrapper {
var value: Int
var wrappedValue: Int {
get { value }
set { value = newValue }
}
var projectedValue: String {
"Value is \(value)"
}
}
struct Example {
@Wrapper var number: Int
}
This code defines a property wrapper with wrappedValue and projectedValue, then uses it in a struct.
Look for repeated actions when accessing these properties.
- Primary operation: Accessing
wrappedValueorprojectedValuecalls a simple getter or setter. - How many times: Each access is a single operation, no loops or recursion involved.
Accessing wrappedValue or projectedValue always takes the same small number of steps, no matter how many times or what values are involved.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 simple property accesses |
| 100 | 100 simple property accesses |
| 1000 | 1000 simple property accesses |
Pattern observation: The time grows directly with the number of accesses, but each access is quick and constant.
Time Complexity: O(1)
This means each access to wrappedValue or projectedValue takes a fixed amount of time, no matter what.
[X] Wrong: "Accessing projectedValue is slower because it creates a new string every time."
[OK] Correct: While projectedValue may compute a value, this computation is simple and constant time, so it does not grow with input size.
Understanding how property wrappers work under the hood helps you explain performance clearly and confidently in interviews.
What if projectedValue computed a value by looping over a large array? How would the time complexity change?
Practice
wrappedValue represent in a Swift property wrapper?Solution
Step 1: Understand the role of wrappedValue
The wrappedValue is the core value that the property wrapper manages or stores internally.Step 2: Differentiate from other features
Unlike projectedValue, wrappedValue is the actual data, not extra info or behavior.Final Answer:
The main value stored or controlled by the property wrapper -> Option AQuick Check:
wrappedValue = main stored value [OK]
- Confusing wrappedValue with projectedValue
- Thinking wrappedValue is a method
- Assuming wrappedValue holds extra metadata
projectedValue of a property wrapper named score?Solution
Step 1: Recall how to access projectedValue
In Swift, the projectedValue is accessed using the dollar sign prefix before the property name.Step 2: Match syntax to property name
For a property named score, the projectedValue is accessed as $score.Final Answer:
$score -> Option BQuick Check:
projectedValue = $propertyName [OK]
- Trying to access projectedValue as a normal property
- Using dot syntax incorrectly
- Confusing $score with score.$projectedValue
@propertyWrapper
struct Capitalized {
private var value: String = ""
var wrappedValue: String {
get { value }
set { value = newValue.capitalized }
}
var projectedValue: String {
"Length: \(value.count)"
}
}
struct Person {
@Capitalized var name: String
}
var p = Person()
p.name = "john doe"
print(p.name)
print(p.$name)Solution
Step 1: Understand wrappedValue behavior
Setting p.name to "john doe" triggers the setter, which capitalizes the string to "John Doe".Step 2: Calculate projectedValue output
The projectedValue returns the length of the capitalized string. "John Doe" has 8 characters including the space.Final Answer:
John Doe\nLength: 8 -> Option AQuick Check:
wrappedValue capitalizes, projectedValue shows length [OK]
- Counting characters without space
- Ignoring capitalization effect
- Using p.name instead of p.$name for projectedValue
@propertyWrapper
struct Trimmed {
var wrappedValue: String {
didSet { wrappedValue = wrappedValue.trimmingCharacters(in: .whitespaces) }
}
}
struct User {
@Trimmed var username: String
}
var u = User()
u.username = " alice "
print(u.username)Solution
Step 1: Check wrappedValue declaration
The wrappedValue property lacks an initial value or backing storage, causing a compile error.Step 2: Understand property wrapper requirements
Property wrappers must have a stored wrappedValue or initializer to set it; here it's missing.Final Answer:
Missing initial value for wrappedValue -> Option CQuick Check:
wrappedValue needs initial value or storage [OK]
- Trying to mutate wrappedValue inside didSet
- Assuming didSet works without storage
- Confusing struct vs class requirement
wrappedValue and projectedValue to achieve this?Solution
Step 1: Define roles of wrappedValue and projectedValue
wrappedValue should hold the main integer value; projectedValue can provide extra info like change count.Step 2: Match roles to requirements
Tracking changes is extra info, so projectedValue is ideal to expose the count without mixing with main value.Final Answer:
Use wrappedValue to store the integer and projectedValue to return the change count -> Option DQuick Check:
wrappedValue = main data, projectedValue = extra info [OK]
- Swapping roles of wrappedValue and projectedValue
- Trying to store multiple values in wrappedValue
- Using projectedValue as main storage
Ready to prove it?
Pass the test and this pattern moves unknown
