问题标签 [swift-concurrency]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
74 浏览

swift - 迭代异步方法以生成数组的最有效方法

如果您有一个生成值的异步方法,那么迭代该方法以生成值数组的最有效方法是什么?

这个类通过使用一个遍历 url 并调用其单值方法的 TaskGroup 来生成一个数组fetch(from:) -> UIImage

该类不调用单值方法。相反,它URLSession.data(from:)手动UIImage(data:)调用。奇怪的是,这比ImageService上面的实现效率低。

此类使用AsyncStream带有展开初始化程序的 an。这是效率最低的方法。

此类使用AsyncStream带有延续初始值设定项的 an。它比上面的实现稍微高效一些。

我很好奇为什么第一个实现是最有效的,尤其是为什么它比第二个实现更有效。至于 AsyncStream 的实现,它们似乎效率很低。

正在使用TaskGroup最好的方法来解决这个问题吗?

这是我在每次迭代时从网络下载 10 张图像时观察到的时间(以毫秒为单位)。

Elapsed [ImageService]:12.93
Elapsed [ImageService]:13.00
Elapsed [ImageService]:16.74
Elapsed [ImageServiceUnrolled]:16.41
Elapsed [ImageServiceUnrolled]:19.06
Elapsed [ImageServiceUnrolled]:17.88
Elapsed [ImageServiceAsyncStreamUnfolding]:28.76
Elapsed [ImageServiceAsyncStreamUnfolding]
: ImageServiceAsyncStreamUnfolding]:28.47
Elapsed [ImageServiceAsyncStreamContinue]:29.55
Elapsed [ImageServiceAsyncStreamContinue]:28.53
Elapsed [ImageServiceAsyncStreamContinue]:27.05

0 投票
1 回答
55 浏览

swiftui - SwiftUI Combine - 如何测试等待发布者的异步结果

我正在监听发布者的更改,然后在我的管道中异步获取一些数据并使用结果更新视图。但是,我不确定如何使它可测试。我怎样才能最好地等到期望得到满足?

看法

视图模型

测试

当前的解决方法

如果我可以fetchResults()使用,我可以异步/等待,这适用于我的单元和快照测试,但我担心:

  1. 如果不被外部调用,那么暴露是不好的做法?
  2. 我没有测试我的发布者管道
0 投票
1 回答
202 浏览

swift - Actor-isolated 属性不能通过“inout”传递给“async”函数调用

我是 Swift 并发的新手(就像大多数人一样,我想),我遇到了一个编译器错误,我不知道该怎么办。

mutate()函数的第一行给了我以下错误。 Actor-isolated property 'thing' cannot be passed 'inout' to 'async' function call

如果我只是继承class而不是UIViewController正常工作,但我需要这里的控制器,所以我需要弄清楚如何在特定的上下文中使其工作。

0 投票
0 回答
120 浏览

ios - 同步使用 `async` 方法

我正在将我的一些异步函数移至新的 Swift 并发机制。在某些时候,我使用完成处理程序将一个方法转换为一个同步方法DispatchGroup(它看起来很奇怪,但这是因为我在一个中使用了这个方法Operation):

我想使用async/做同样的事情await。然而,当简单地转换代码时,我得到一个编译器错误:

并发执行代码中捕获的 var 'result' 的突变

有没有其他方法可以通过新的 API 实现这一点?

0 投票
1 回答
69 浏览

swift - 制作包含可发送闭包的结构是否安全?

我想要一个Sendable包含闭包的结构。此闭包接受引用类型,但返回Void,因此Greeter不直接存储Person引用。然而,闭包本身仍然是引用。

当前代码:

在我的实际问题(这是简化的)中,我实际上并不知道Person它的实现,因此无法标记它Sendable。它实际上是一个MTLRenderCommandEncoder,但为简单起见,我们只有Person.

greet定义上,我收到以下警告:

符合“Sendable”的结构“Greeter”的存储属性“greet”具有不可发送类型“(Person)-> Void”

我可以使警告消失,但我认为这不是安全且正确的解决方案:

如何确保此代码跨线程安全?

0 投票
0 回答
133 浏览

swift - Swift await/async - 如何同步等待异步任务完成?

我正在桥接 Swift 中的同步/异步世界,并逐步采用异步/等待。我正在尝试调用从非异步函数返回值的异步函数。我知道显式使用 ofTask是这样做的方式,如描述的,例如,here

该示例并不真正适合,因为该任务不返回值。

经过大量搜索,我无法找到任何关于我认为很常见的问题的描述:异步任务的同步调用(是的,我知道这会冻结主线程)。

我理论上想在我的同步函数中写的是:

但是,当我尝试这样做时,由于尝试访问而出现此编译器错误result

'async' property access in a function that does not support concurrency

我发现的另一种选择是:

wheremyResult必须归属为@State成员变量。

但是,这并不像我想要的那样工作,因为无法保证在Task.init()完成并进入下一个语句之前完成该任务。那么我怎样才能同步等待该任务完成呢?

0 投票
2 回答
42 浏览

swift - 使用未命名的 async let 同时运行异步任务

使用 Swift 并发,是否有可能拥有类似“未命名”的东西async let

这是一个例子。您有以下演员:

现在我想设置foobar使用给定的方法。简单的用法如下所示:

但是,此代码是按顺序运行的。出于所有意图和目的,假设setFoo(to:)并且setBar(to:)可能是一项长期运行的任务。您还可以假设这些方法是互斥的(不共享变量并且不会相互影响)。

要使此代码成为最新的,async let可以使用。但是,这只是启动任务,直到它们await稍后被编辑。在我的示例中,您会注意到我不需要这些方法的返回值。我所需要的只是在printResult()调用之前,之前的任务已经完成。

我可以想出以下内容:

显式创建这些任务然后awaiting 一组它们似乎是不正确的。这真的是最好的方法吗?

0 投票
0 回答
50 浏览

swift - 如何在不使用演员的情况下使用新的 Task api 可预测地序列化一些异步代码的执行顺序?

看起来 Swift 新的并发模型与旧的并发模型不兼容。我已经尝试为我的新异步函数逐步采用新的 swift 并发模型(使用 async/await 仪式),但是当避免数据竞争问题的传统方法(在串行队列上调度任务)确实如此时,我很快就碰壁了不再工作了。我知道新模型使用演员来处理这个问题,但我认为 2 世界可以生活​​在一起,但没有找到解决方案。为了证明我的问题,请检查以下代码。Playground 结果表明,Task 2 的一些代码在 Task 1 完成之前执行,这使得 queue.async 无能为力,这与开发人员的预期背道而驰。有没有办法在不使用演员的情况下序列化任务?

0 投票
1 回答
64 浏览

swift - SWIFTUI:从“(IndexSet)异步”类型的“异步”函数转换无效

我正在学习 SWIFTUI 并尝试做一些应用程序来测试我的知识,而无需真正遵循教程,因为我喜欢思考为什么事情会以某种方式工作。这就是我学习的方式:)

所以,我试图调用一个函数来通过 API 发布一些数据。该方法位于 ViewModel 内部。视图是一个列表,我需要能够触发 .OnDelete 修饰符才能通过视图模型触发 API 调用。

但我总是面临错误:

从 '(IndexSet) async -> Void' 类型的 'async' 函数到同步函数类型 '(IndexSet) -> Void' 的无效转换

这是代码。

在 ContentView.swift 中:

在 PostViewModel.swift 中:

我在这里做错了什么?

0 投票
1 回答
116 浏览

ios - Xcode 在 Swift 异步函数中使用 await UIApplication.shared.open(settingsURL) 时发出警告

await UIApplication.shared.open(settingsURL)在 Swift 内部调用,Task但收到 Xcode 运行时警告:

UIApplication.open(_:options:completionHandler:) 只能在主线程中使用

SDK 显示了这些方法:

错误消息暗示它认为我正在使用第一个非异步的(因为提到了完成处理程序),但我不是。UIApplication被标记,MainActor所以我的理解是通过实例调用的所有内容都UIApplication自动在主线程上运行。这适用于我在其他地方调用的UIApplication其他内容,例如isRegisteredForRemoteNotifications.

该应用程序运行良好,没有崩溃或任何事情,只是来自 Xcode 的警告。

Xcode 只是在这里感到困惑还是我实际上做错了什么?

截屏:

错误截图

编辑:对于那些感到困惑的人MainActor,这是一个有用的阅读:https ://www.swiftbysundell.com/articles/the-main-actor-attribute/

我可以换行UIApplication.shared.open(settingsURL)await MainActor.run但我仍然很困惑为什么MainActor在这里不起作用/为什么 Xcode 认为调用了错误的方法。