Как я могу реализовать наблюдатель свойств в структуре оболочки свойств в Swift?

Поскольку наблюдатели за свойствами наблюдают за изменениями и реагируют на них, и это то, что они делают, почему они не отображаются в оболочке свойства?

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)

Возникла ошибка в вызывающих объектах-наблюдателях свойства willSet() и didSet(). Хотя я его не устанавливал, игровая площадка выдает ошибку. Может ли кто-нибудь сказать мне, если я делаю это или как мне это сделать?


person Aman    schedule 12.07.2020    source источник


Ответы (1)


Обертки свойств — это просто классы/структуры. На самом деле они сами по себе не являются свойствами. Они оборачивают свойство с именем wrappedValue. Таким образом, чтобы наблюдать за оболочкой свойства, вы должны наблюдать за его wrappedValue.

wrappedValue в вашем коде является вычисляемым свойством. Вычисляемым свойствам не нужны наблюдатели за свойствами. См. этот мой ответ, почему. Если вы хотите соблюсти wrappedValue, просто напишите нужный код в set:

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

Вы можете наблюдать это, если wrappedValue было хранимым свойством:

@propertyWrapper
struct Property {

    ...

    var wrappedValue: Int {
        didSet { ... }
        willSet { ... }
    }
}
person Sweeper    schedule 12.07.2020
comment
Ага. Или вы можете просто добавить своих наблюдателей в number. - person Rob; 12.07.2020