如果我运行下面的代码,它将正确计数到10,然后跳过每个奇数。
如果让它运行超过20,它将开始跳过越来越多的内容(输出将类似于1-2-3-4-5-6-7-8-9-10-12-14-16- 18-20-23-26-29 ...)。
找不到相关文档,例如计划任务的数量有限,所以请问您:) 从昨天开始学习SwiftUI,请原谅这是一个明显的问题。
如果将其安排在与main不同的DispatchQueue中,则没有任何区别。
感谢您的帮助!
import SwiftUI
struct ContentView: View {
@State private var counter : Int = 0
func buttonTap() {
let time : DispatchTime = .now()
var delay : Double = 0
for _ in 1...50 {
delay = delay + 0.2
DispatchQueue.main.asyncAfter(deadline: time + delay) {
counter += 1
}
}
}
var body: some View {
ZStack {
Color(.black)
.edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
Text(String(counter))
.foregroundColor(.green)
.padding()
Text("Button")
.foregroundColor(.green)
.offset(y: 50)
.onTapGesture(perform: {
buttonTap()
})
}
}
}
答案 0 :(得分:1)
这是一种奇怪的行为,甚至在事件之间的间隔时间更长(例如2秒)。
考虑改用Timer
:
您可以使用多个单独的火灾计时器,这些计时器的工作方式与单独的调度一样:
func buttonTap() {
var delay : Double = 0
for _ in 1...50 {
delay = delay + 0.2
Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { timer in
self.counter += 1
}
}
}
或每0.2
秒触发一次的单个计时器:
func buttonTap() {
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) { timer in
self.counter += 1
if counter == 50 {
timer.invalidate()
}
}
}
答案 1 :(得分:1)
此行为称为计时器合并,其中在彼此之间10%之内发生的独立计划的事件将被合并在一起,并将同时运行。这是一项省电功能。
有多种解决方案可以避免合并:
重复计时器是最常见的解决方案。