为什么 macOS 14 上的 SwiftUI 中的任务不能同时运行?

问题描述 投票:0回答:1

我在 Sonoma 下运行 SwiftUI 时遇到一个奇怪的问题,因为两个任务不再异步运行。我确信这在升级之前是有效的。

这是我的代码:

import SwiftUI

struct ContentView: View 
{
    var body: some View
    {
        Button("Press me")
        {
           Task
           {
                for i in (1...5)
                {
                    print ("a", i)
                    sleep(1)
                }
            }
            Task
            {
                for i in (1...5)
                {
                    print ("b", i)
                    sleep(1)
                }
            }
        }
    }
}

输出为:

a 1
a 2
a 3
a 4
a 5
b 1
b 2
b 3
b 4
b 5

或者有点奇怪:

b 1
b 2
b 3
b 4
b 5
a 1
a 2
a 3
a 4
a 5

如果我在操场上运行它,那么一切都会按预期工作,两个任务的输出混合在一起。

正如我所说,这在升级之前确实有效,所以我现在应该做什么才能正确执行此操作?

macos swiftui task
1个回答
0
投票
  1. 在 SwiftUI 中是
    .task
    而不是
    Task {}
  2. 暂停它是
    Task.sleep(for: .seconds(1))
    而不是
    sleep(1)
  3. 要拥有 2 个嵌套任务但仍支持取消,您需要使用
    TaskGroup
    ,请参阅此 answer 了解更多信息。

做的所有事情应该看起来像这样:

struct ContentView: View
{
    @State var isRunning = false

    var body: some View
    {
        Button("\(isRunning ? "Stop" : "Start")")
        {
            isRunning.toggle()
        }
        .task(id: isRunning) { // runs on appear and cancelled and restarted when id changes.
            if(!isRunning){
                return
            }
            await withTaskGroup(of: Void.self) { group in
                group.addTask {
                    for i in (1...5)
                    {
                        print ("a", i)
                        do {
                            try await Task.sleep(for: .seconds(1))
                        }
                        catch {
                            break // cancelled
                        }
                    }
                }
                group.addTask {
                    
                    for i in (1...5)
                    {
                        print ("b", i)
                        do {
                            try await Task.sleep(for: .seconds(1))
                        }
                        catch {
                            break // cancelled
                        }
                    }
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.