Как вы открываете закрытие из @propertywrapper? - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь написать оболочку свойства, чтобы связать две переменные вместе. У меня проблема в том, что когда я вызываю свойство projectedValue, мое замыкание возвращает ноль. Я хочу иметь возможность назначить значение закрытию после изменения значения наблюдаемого элемента.

Это мой класс оболочки свойств.

@propertyWrapper
class State<Instance> {

    typealias projectedClosure = (Instance) ->Void


    init(wrappedValue: Instance) {
        self.instance = wrappedValue
    }

     var projectedValue : Binding<Instance>  {
        Binding<Instance>(value: instance)
    }

    private var instance : Instance {
        didSet{
            projectedValue.value = instance
        }
    }

    var wrappedValue: Instance {
        get{
            return instance
        }
        set{
            instance = newValue
        }
    }
}

PropertyWrapper проецирует этот класс

class Binding<Element> {

    var handler : ((Element)->Void)?

    var value :Element {
        didSet{
            guard let handlerClosure = handler else {
                print("Handler is null")
                return
            }
            handlerClosure(value)
        }
    }

    init(value:Element) {
        self.value = value
    }
}

Наконец, я реализую это на игровой площадке, прежде чем перенести его в мой актуальный проект. Вот как я выполняю методы.

class TestPropertyWrapperObserver {

    @State var name : String

    init(name:String) {
        self.name = name
    }
}

var test = TestPropertyWrapperObserver(name: "Thomas")

var ryan = "ryan"

test.$name.handler = { item in
    ryan = item
    print(item)
}

test.name = "bradly"
test.name = "fake"

print(ryan)

Мой журнал печати:

Handler is null
Handler is null
ryan

1 Ответ

1 голос
/ 25 апреля 2020

Ваша ошибка в том, что вы сделали projectedValue вычисляемое свойство, поэтому каждый раз, когда вы делаете это:

projectedValue.value = instance

новый Binding экземпляр создается.

Вместо этого вы должны сделать projectedValue сохраненным свойством и инициализировать его в init, один раз :

init(wrappedValue: Instance) {
    self.instance = wrappedValue
    projectedValue = Binding<Instance>(value: instance)
}

let projectedValue : Binding<Instance>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...