我试图写一个属性包装器来将两个变量绑定在一起。我遇到的问题是,当我调用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
你的错误是你做了 projectedValue
一个计算过的属性,所以每次你这样做。
projectedValue.value = instance
a 新的 Binding
实例被创建。
相反,你应该让 projectedValue
存储的属性,并将其初始化为 init
, 曾经:
init(wrappedValue: Instance) {
self.instance = wrappedValue
projectedValue = Binding<Instance>(value: instance)
}
let projectedValue : Binding<Instance>