你如何从@propertywrapper 中公开闭包?
How do you expose a closure from within a @propertywrapper?
我正在尝试编写一个 属性 包装器来将两个变量绑定在一起。我遇到的问题是,当我调用 projectedValue 属性 我的闭包 returns 为零时。一旦观察项的值发生更改,我希望能够为闭包分配一个值。
这是我的 属性 包装纸 class。
@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
}
}
}
属性Wrapper 投射这个 class
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
创建了一个new Binding
实例。
相反,您应该将 projectedValue
存储为 属性,并在 init
中初始化它,一次:
init(wrappedValue: Instance) {
self.instance = wrappedValue
projectedValue = Binding<Instance>(value: instance)
}
let projectedValue : Binding<Instance>
我正在尝试编写一个 属性 包装器来将两个变量绑定在一起。我遇到的问题是,当我调用 projectedValue 属性 我的闭包 returns 为零时。一旦观察项的值发生更改,我希望能够为闭包分配一个值。
这是我的 属性 包装纸 class。
@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
}
}
}
属性Wrapper 投射这个 class
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
创建了一个new Binding
实例。
相反,您应该将 projectedValue
存储为 属性,并在 init
中初始化它,一次:
init(wrappedValue: Instance) {
self.instance = wrappedValue
projectedValue = Binding<Instance>(value: instance)
}
let projectedValue : Binding<Instance>