Swift return/completion 后任务会自动取消吗?

Are Tasks automatically cancelled upon return/completion in Swift?

我对 swift 中的任务取消有点不确定。我的问题是:

如果一个任务到达了它的 return 行(在这个例子中,Line 4),这是否意味着它会被自动取消?(因此释放内存 + 任务之前占用的任何已用线程?)

someBlock {
    Task<Bool, Never> {
        await doSomeWork()
        return true // Line 4
    }
}

作为后续行动,如果我们随后在 SwiftUI View 上调用 .task 会怎样?有什么变化吗?

SomeView
    .task {
        await doSomeWork()
    }

感谢您的宝贵时间!

If a task reaches its return line (in this example, Line 4), does this mean it will be automatically canceled

没有。这意味着它将自动 以良好的顺序结束。 取消任务是非常不同和专门的事情。它们都是结束任务的方式,但在这种相似性中,它们实际上是相反的。

这确实意味着任务使用的线程现在可以免费使用,但这并不像看起来那么重要,因为 await 释放任务使用的线程。这就是async/await的全部;它不是 thread-bound。 Task 不像 DispatchQueue 那样与单个线程对齐;换句话说,我们倾向于使用队列和线程作为松散的等价物,但对于任务,情况完全不同。

至于释放什么内存,要看保留什么内存。给出的代码太“伪”了,无法得出任何结论。但基本上是的,你的想法是正确的:一个 Task 有它自己的生命,并且在它存在的时候它的代码继续保留它有强引用的任何东西,然后当它结束时(无论是通过良好的顺序完成或通过取消)任务的生命结束(如果您没有在其他地方保留它)因此任务代码保留的任何内容也会结束。

Does anything change

根据 Apple 的说法,.task 修饰符创建“一个异步任务,其生命周期与...视图相匹配”。所以我会说,是的:Task 不再只是拥有自己的独立生命,而是被保留在幕后(以便 SwiftUI 框架可以在 View 不存在时取消它),等等其代码具有强引用的任何内容都将保留。

另一方面,这可能不是特别重要;这取决于您是否使用引用类型。对值类型(例如视图)的引用没有那种内存管理含义。