如何解决为什么要捕获onChangeof:perform :)的参数?
我正在使用onChange(of:perform:)
SwiftUI修饰符。然后,我想获取旧值,将其与新值进行比较。我阅读了说明文件:
闭包可能会捕获先前的值,以将其与新值进行比较。
举个例子:
.onChange(of: playState) { [playState] newState in
model.playStateDidChange(from: playState,to: newState)
}
我的问题是,为什么在示例中playState
中捕获了[ ]
?无需传递playState
值就可以很容易地对其进行访问。此外,这也不是类的一部分,因此我认为无法通过捕获某种类型的self
来创建强引用
为什么示例是这样写的?
解决方法
在“正常”情况下,在不可变值类型(例如struct
)中定义的闭包捕获其值,该值不变,因此一切都很好。
struct Foo {
var a = "original"
func makeFn() -> () -> Void {
return { print(a) }
}
}
var foo = Foo()
let fn = foo.makeFn()
foo.a = "changed"
fn() // "original"
但是使用@State
时,实际值存储在SwiftUI维护的某个全局存储中,因此它的行为基本上就像具有引用语义一样。
调用闭包时,状态值已经更改,因此如上所述的print(a)
通过@State
属性包装器访问一个值,该包装器检索随后更新的值。
要解决这个问题,您可以使用捕获列表将属性捕获到闭包的局部变量中:
return { [a] in print(a) }
这当然是一个简化的示例,SwiftUI可能在幕后做其他事情,但我认为它传达了这一点。
要了解SwiftUI的不同之处,请尝试以下操作:
.onChange(of: playState) { [playState] newState in
print(playState,self.playState,newState)
}
输出将是这样的:
original new new
playState
是定义闭包时(即计算body
时捕获的局部变量),self.playState
通过@State
访问值,该值已更改,而newState
显然是带有新值的传入参数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。