SwiftUI DispatchQueue按钮

时间:2019-07-15 01:58:25

标签: ios swift swiftui

我不了解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
        }
    }
}

为什么计数器不像第一个示例那样继续递增?

1 个答案:

答案 0 :(得分:2)

在第一段代码中,每次评估按钮的start时,您都会调用body

start(最终)更新counter,这是绑定到按钮的Text的状态。更新绑定状态会使SwiftUI再次评估body var。这将调用start,后者将调用asyncAfter,并且该过程将无限期地重复。正如罗布(Rob)在评论中指出的那样,这不是一个很好的方法-body可能随时随地被调用,因此您不能保证每秒只能更新一次。

在第二段代码中,仅在点击按钮时才调用startcounter将在一秒钟后更新,并且Text被更新。除非再次点击该按钮,否则什么都不会发生。