You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS 14(Sonoma)下SwiftUI任务无法并发运行,如何正确实现?

Sonoma系统下SwiftUI任务并发异常问题解决

在Sonoma系统中使用SwiftUI时,两个Task无法异步并发执行,系统升级前可正常工作。代码如下:

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

但在Playground中运行时,两个任务输出会交错显示,符合并发预期。


问题原因

  1. sleep的阻塞特性:sleep(1)是阻塞式函数,会占用当前线程直到休眠结束,无法让调度器切换到其他任务。
  2. Actor上下文继承:SwiftUI的Button动作闭包默认运行在MainActor上,直接创建的Task会继承这个串行Actor上下文,导致两个任务只能按顺序执行,无法并发。而Playground的执行环境没有强制绑定到串行Actor,所以能表现出并发效果。

正确实现并发的方法

方法1:使用Task.detached脱离当前Actor上下文

通过Task.detached创建不继承当前Actor的任务,让任务在全局并发队列执行:

Button("Press me")
{
    Task.detached {
        for i in (1...5)
        {
            print ("a", i)
            sleep(1)
        }
    }
    Task.detached {
        for i in (1...5)
        {
            print ("b", i)
            sleep(1)
        }
    }
}

方法2:使用异步休眠替代阻塞式sleep

用try await Task.sleep(nanoseconds:)替代sleep,它是异步非阻塞的,能让系统调度器合理分配线程,即使在MainActor上下文也能实现任务切换(注意需要处理抛出的错误):

Button("Press me")
{
    Task
    {
        for i in (1...5)
        {
            print ("a", i)
            try await Task.sleep(nanoseconds: 1_000_000_000)
        }
    }
    Task
    {
        for i in (1...5)
        {
            print ("b", i)
            try await Task.sleep(nanoseconds: 1_000_000_000)
        }
    }
}

如果不需要处理错误,也可以用try? await忽略错误:

try? await Task.sleep(nanoseconds: 1_000_000_000)

两种方法都能让任务实现并发执行,输出会交错显示。


内容的提问来源于stack exchange,提问作者iphaaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:00:17