Swift, Property Wrappers

Swift Property Wrappers tutorial and usage examples

✍️ Note

Some codes and contents are sourced from Apple’s official documentation. This post is for personal notes where I summarize the original contents to grasp the key concepts

Property Wrappers

A property wrapper adds a layer of separation between code that manages how a property is stored and the code that defines a property. For example, if you have properties that provide thread-safety checks or store their underlying data in a database, you have to write that code on every property. When you use a property wrapper, you write the management code once when you define the wrapper, and then reuse that management code by applying it to multiple properties.

When you apply a wrapper to a property, the compiler synthesizes code that provides storage for the wrapper and code that provides access to the property through the wrapper. (The property wrapper is responsible for storing the wrapped value, so there’s no synthesized code for that.) 

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties

screenshot 2024 03 16 at 2.43.04e280afpm

Wrapped Value

struct SmallRectangle {
    private var _height = TwelveOrLess()
    private var _width = TwelveOrLess()
    var height: Int {
        get { return _height.wrappedValue }
        set { _height.wrappedValue = newValue }
    }
    var width: Int {
        get { return _width.wrappedValue }
        set { _width.wrappedValue = newValue }
    }
}

projected Value

The name of the projected value is the same as the wrapped value, except it begins with a dollar sign ($)

Apple

@propertyWrapper
struct TwelveOrLess {
    private var number = 0
    private(set) var projectedValue = true
    var wrappedValue: Int {
        get { return number }
        set {
            number = min(newValue, 12)
            projectedValue = number == 0
        }
    }
    
    init() {
        self.number = 0
        self.projectedValue = true
    }
}

struct Number {
    @TwelveOrLess var lessNumber
}

var number = Number()
number.lessNumber = 10
number.$lessNumber

Projected Value, property name should be projectedValue

And Compiler doesn’t allow to mutating the projectedValue from the others. So Access control for it, setting the private(set) var is make sense.

Comments

Leave a Reply

Discover more from Shawn

Subscribe now to keep reading and get access to the full archive.

Continue reading