SwiftUI DispatchQueue asyncAfter在完成十个计划任务后停止正常工作
如果我运行下面的代码,它将正确计数为10,然后跳过每个奇数 如果让它运行超过20,它将开始越来越多地跳过(输出将类似于1-2-3-4-5-6-7-8-9-10-12-14-16-18-20-23-26-29…) 找不到文档,例如计划任务的限制,因此询问您:) 从昨天开始学习SwiftUI,如果这是一个明显的问题,请原谅 如果它被安排在与main不同的DispatchQueue中,则没有区别 谢谢你的帮助SwiftUI DispatchQueue asyncAfter在完成十个计划任务后停止正常工作,swift,swiftui,grand-central-dispatch,Swift,Swiftui,Grand Central Dispatch,如果我运行下面的代码,它将正确计数为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 {
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()
})
}
}
}
这是一种奇怪的行为,它甚至会在事件之间出现更长的时间间隔(例如,2秒) 考虑改用
计时器
:
您可以使用多个单一火灾计时器,其工作方式与您的单独调度相同:
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()
}
}
}
这是一种奇怪的行为,它甚至会在事件之间出现更长的时间间隔(例如,2秒) 考虑改用
计时器
:
您可以使用多个单一火灾计时器,其工作方式与您的单独调度相同:
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()
}
}
}
这种行为被称为计时器合并,在这种情况下,相互间隔不超过10%的独立计划事件将合并在一起,并同时运行。这是一种省电功能 有多种解决方案可避免凝聚:
- 使用重复计时器李>
- 在前一个迭代的完成处理程序中安排每个迭代;或
- 创建“严格”的GCD计时器,它不会被合并
重复计时器是最常见的解决方案。这种行为称为计时器合并,在这种情况下,发生在彼此10%以内的独立计划事件将合并在一起,并同时运行。这是一种省电功能 有多种解决方案可避免凝聚:
- 使用重复计时器李>
- 在前一个迭代的完成处理程序中安排每个迭代;或
- 创建“严格”的GCD计时器,它不会被合并
重复计时器是最常见的解决方案。我在这里没有看到任何缺陷-计数器的更新速度比UI快,所以您不会看到所有情况。你为什么要这样做?我正在制作一个呼吸冥想应用程序,它有几秒钟的延迟…但是,例如,它只是超过了几秒钟的暂停时间,直接开始下一个任务…不要认为,这是因为缓慢的UI更新?还是这样?即使在更复杂的应用程序中,问题也会在十个任务后出现。我在这里看不到任何缺陷-计数器的更新速度比UI快,所以您不会看到所有情况。你为什么要这样做?我正在制作一个呼吸冥想应用程序,它有几秒钟的延迟…但是,例如,它只是超过了几秒钟的暂停时间,直接开始下一个任务…不要认为,这是因为缓慢的UI更新?还是这样?即使在更复杂的应用程序中,问题也会在完成十项任务后出现。非常感谢,它是这样工作的!是否允许我将您的问题标记为解决方案(因为它显示了另一种方式,并且没有解释DispatchQueue行为)?是的,作为问题作者,您可以将任何答案标记为您认为合适的解决方案。如果有更好的答案出现,你也可以更改被接受的答案,这样它就不会一成不变了。非常感谢,它是这样工作的!是否允许我将您的问题标记为解决方案(因为它显示了另一种方式,并且没有解释DispatchQueue行为)?是的,作为问题作者,您可以将任何答案标记为您认为合适的解决方案。如果有更好的答案出现,你也可以修改被接受的答案,这样它就不会一成不变了。