考虑以下代码,它在视图的.background修饰符中放置了波动的CatView:

@State private var catOn = true

...

SomeView()
.background {
    GeometryReader { geo in
        ForEach(0...numCats, id: \.self) { n in
            CatView(color: n%2 == 0 ? color1 : color2, size: 15, isOn: n%2 == 0 ? catOn : !catOn)
            //.frame = ...
        }
        .task {
            while !Task.isCancelled {
                try? await Task.sleep(for: .seconds(1.0))
                catOn.toggle()
            }
        }
    }
    
}

问题是,当视图被另一个视图替换时,我认为这段代码有时会导致崩溃,这可能是因为任务在过渡期间触发(当我注释掉.task时,我没有看到崩溃).在触发转移此视图的属性之前,当按下按钮时,如何取消此任务?还有,有没有更好的方法来设置这个任务?如你所见,我需要CatViews每秒交换 colored颜色 .

推荐答案

首先,您应该捕捉sleep引发的取消错误,以便在sleep期间取消任务时不会切换catOn:

while !Task.isCancelled {
    do {
        try await Task.sleep(for: .seconds(1.0))
        catOn.toggle()
    } catch is CancellationError {
        return // the task is cancelled during the sleep
    } catch {
        fatalError("Something unexpected happened")
    }
}

只有当视图消失时,该任务才会被取消.要立即按需取消任务,可以使用task(id:)重载.当该id改变时,当前运行的任务被取消,并且开始新的任务.你可以在return时立即对新的id值进行一些哨兵.例如:

@State var cancelled = false
@State var catOn = false

var body: some View {
    Toggle("Cat On", isOn: $catOn)
    
    Button("Cancel Task") {
        cancelled = true
    }
    .task(id: cancelled) {
        if cancelled { return }

        while !Task.isCancelled {
            do {
                try await Task.sleep(for: .seconds(1.0))
                catOn.toggle()
            } catch is CancellationError {
                return
            } catch {
                fatalError("Something unexpected happened")
            }
        }
    }
}

Swift相关问答推荐

Swift 5.10:无法从非隔离的deinit访问属性*,这是Swift 6中的错误''''

绑定到可选值的非可选属性?'

阻塞(受CPU限制的)任务的异步功能?

';NSInternal不一致异常';,原因:';可见导航栏Xcode 15.0 Crash请求布局

如何在macOS中延迟退出应用程序的退出操作?

ClosedRange.Swift 中 Int 的索引?

为什么无法在 Swift 中使用AVFoundation扫描 QRCode

暂停我的 AR 会话并清除变量和锚点的功能

ConfirmationDialog取消swiftui中的错误

使用 WrappingHStack 文本溢出到新行

试图同时实现两个混合过渡

故事板未在助手中显示视图控制器

如何在 SwiftUI 的 fileImporter 中为 allowedContentTypes 设置 xcodeproj 类型?

为什么 swift 中的类没有存储类型属性?

Swift 4 Decodable - 以枚举为键的字典

如何在 Swift 中复制字典?

如何在 Swift 中将 UILabel 居中?

更改日期 Select 器的文本 colored颜色

使用 swift IOS 使 UIBarButtonItem 消失

iPhone 纵向和 iPad 横向的通用应用程序