Aman
Aman

Reputation: 39

How can I implement a property observer in a property wrapper structure in swift?

Because property observers observe and respond to changes, and that's what they do, why are they not showing up in a property wrapper?

import Foundation

@propertyWrapper
struct Property {
    
    private var number: Int = 0
    private var maximum: Int = 0
    
    var wrappedValue: Int {
        
        get { return number }
        set { number = min(newValue, maximum) }
    }

    init() {
        maximum = 12
        number = 0
    }
    
    init(wrappedValue: Int) {
        maximum = 12
        number = min(wrappedValue, maximum)
    }
    
    init(wrappedValue: Int, maximum: Int) {
        self.maximum = maximum
        number = min(wrappedValue, maximum)
    }
    
    willSet() {}
    didSet() {}
}


struct SmallRectangle {
    
    @Property(wrappedValue: 12, maximum: 25) var _height: Int
    @Property(wrappedValue: 12, maximum: 25) var _width: Int
}

var smallRectangle = SmallRectangle()
smallRectangle._height = 18

print(smallRectangle._height)

There is an error at the willSet() and didSet() property observer callers. Although I haven't set it, the playground prompts me with an error. Can someone tell me if I do that or how do I do that?

Upvotes: 3

Views: 693

Answers (1)

Sweeper
Sweeper

Reputation: 270995

Property wrappers are really just classes/structs. They are not actually properties themselves. They wrap a property called wrappedValue. So to "observe" a property wrapper, you should observe its wrappedValue.

wrappedValue in your code is a computed property. Computed properties don't need property observers. See this answer of mine for why. If you want to "observe" wrappedValue, just write the code you want in set:

var wrappedValue: Int {
    
    get { return number }
    set { 
        // write willSet here...
        number = min(newValue, maximum) 
        // write didSet here...
    }
}

You can observe it if wrappedValue were a stored property:

@propertyWrapper
struct Property {

    ...

    var wrappedValue: Int {
        didSet { ... }
        willSet { ... }
    }
}

Upvotes: 1

Related Questions