我不了解SwiftUI和DispatchQueues如何工作的问题。这是代码。
这有效,并且将继续每秒刷新计数器状态变量。
// Example 1 - This works
struct TimerButtonTest : View {
@State var counter: Int = 0
var body: some View {
start()
return VStack { Text("\(counter)") }
}
func start() {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) {
self.counter += 1
}
}
}
不是。按下按钮后,计数器会增加1(1秒后),但会停止。
// Example 2 - This does not work
struct TimerButtonTest : View {
@State var counter: Int = 0
var body: some View {
return Button(action: {self.start()}, label: {Text("\(counter)")})
}
func start() {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) {
self.counter += 1
}
}
}
为什么计数器不像第一个示例那样继续递增?
答案 0 :(得分:2)
在第一段代码中,每次评估按钮的start
时,您都会调用body
。
start
(最终)更新counter
,这是绑定到按钮的Text
的状态。更新绑定状态会使SwiftUI再次评估body
var。这将调用start
,后者将调用asyncAfter
,并且该过程将无限期地重复。正如罗布(Rob)在评论中指出的那样,这不是一个很好的方法-body
可能随时随地被调用,因此您不能保证每秒只能更新一次。
在第二段代码中,仅在点击按钮时才调用start
。 counter
将在一秒钟后更新,并且Text
被更新。除非再次点击该按钮,否则什么都不会发生。