如何在@propertywrapper中暴露一个闭包?

问题描述 投票:0回答:1

我试图写一个属性包装器来将两个变量绑定在一起。我遇到的问题是,当我调用projectionValue属性时,我的闭包返回nil。我希望一旦观察项的值发生变化,就能给闭包分配一个值。

这是我的属性包装器类。

@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
ios swift generics properties closures
1个回答
1
投票

你的错误是你做了 projectedValue 一个计算过的属性,所以每次你这样做。

projectedValue.value = instance

a 新的 Binding 实例被创建。

相反,你应该让 projectedValue 存储的属性,并将其初始化为 init, 曾经:

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

let projectedValue : Binding<Instance>
© www.soinside.com 2019 - 2024. All rights reserved.