问题标签 [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.
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
swiftui - SwiftUI Combine - 如何测试等待发布者的异步结果
我正在监听发布者的更改,然后在我的管道中异步获取一些数据并使用结果更新视图。但是,我不确定如何使它可测试。我怎样才能最好地等到期望得到满足?
看法
视图模型
测试
当前的解决方法
如果我可以fetchResults()
使用,我可以异步/等待,这适用于我的单元和快照测试,但我担心:
- 如果不被外部调用,那么暴露是不好的做法?
- 我没有测试我的发布者管道
swift - Actor-isolated 属性不能通过“inout”传递给“async”函数调用
我是 Swift 并发的新手(就像大多数人一样,我想),我遇到了一个编译器错误,我不知道该怎么办。
该mutate()
函数的第一行给了我以下错误。
Actor-isolated property 'thing' cannot be passed 'inout' to 'async' function call
如果我只是继承class
而不是UIViewController
正常工作,但我需要这里的控制器,所以我需要弄清楚如何在特定的上下文中使其工作。
ios - 同步使用 `async` 方法
我正在将我的一些异步函数移至新的 Swift 并发机制。在某些时候,我使用完成处理程序将一个方法转换为一个同步方法DispatchGroup
(它看起来很奇怪,但这是因为我在一个中使用了这个方法Operation
):
我想使用async
/做同样的事情await
。然而,当简单地转换代码时,我得到一个编译器错误:
并发执行代码中捕获的 var 'result' 的突变
有没有其他方法可以通过新的 API 实现这一点?
swift - 制作包含可发送闭包的结构是否安全?
我想要一个Sendable
包含闭包的结构。此闭包接受引用类型,但返回Void
,因此Greeter
不直接存储Person
引用。然而,闭包本身仍然是引用。
当前代码:
在我的实际问题(这是简化的)中,我实际上并不知道Person
它的实现,因此无法标记它Sendable
。它实际上是一个MTLRenderCommandEncoder
,但为简单起见,我们只有Person
.
在greet
定义上,我收到以下警告:
符合“Sendable”的结构“Greeter”的存储属性“greet”具有不可发送类型“(Person)-> Void”
我可以使警告消失,但我认为这不是安全且正确的解决方案:
如何确保此代码跨线程安全?
swift - Swift await/async - 如何同步等待异步任务完成?
我正在桥接 Swift 中的同步/异步世界,并逐步采用异步/等待。我正在尝试调用从非异步函数返回值的异步函数。我知道显式使用 ofTask
是这样做的方式,如描述的,例如,here。
该示例并不真正适合,因为该任务不返回值。
经过大量搜索,我无法找到任何关于我认为很常见的问题的描述:异步任务的同步调用(是的,我知道这会冻结主线程)。
我理论上想在我的同步函数中写的是:
但是,当我尝试这样做时,由于尝试访问而出现此编译器错误result
:
'async' property access in a function that does not support concurrency
我发现的另一种选择是:
wheremyResult
必须归属为@State
成员变量。
但是,这并不像我想要的那样工作,因为无法保证在Task.init()
完成并进入下一个语句之前完成该任务。那么我怎样才能同步等待该任务完成呢?
swift - 使用未命名的 async let 同时运行异步任务
使用 Swift 并发,是否有可能拥有类似“未命名”的东西async let
?
这是一个例子。您有以下演员:
现在我想设置foo
和bar
使用给定的方法。简单的用法如下所示:
但是,此代码是按顺序运行的。出于所有意图和目的,假设setFoo(to:)
并且setBar(to:)
可能是一项长期运行的任务。您还可以假设这些方法是互斥的(不共享变量并且不会相互影响)。
要使此代码成为最新的,async let
可以使用。但是,这只是启动任务,直到它们await
稍后被编辑。在我的示例中,您会注意到我不需要这些方法的返回值。我所需要的只是在printResult()
调用之前,之前的任务已经完成。
我可以想出以下内容:
显式创建这些任务然后await
ing 一组它们似乎是不正确的。这真的是最好的方法吗?
swift - 如何在不使用演员的情况下使用新的 Task api 可预测地序列化一些异步代码的执行顺序?
看起来 Swift 新的并发模型与旧的并发模型不兼容。我已经尝试为我的新异步函数逐步采用新的 swift 并发模型(使用 async/await 仪式),但是当避免数据竞争问题的传统方法(在串行队列上调度任务)确实如此时,我很快就碰壁了不再工作了。我知道新模型使用演员来处理这个问题,但我认为 2 世界可以生活在一起,但没有找到解决方案。为了证明我的问题,请检查以下代码。Playground 结果表明,Task 2 的一些代码在 Task 1 完成之前执行,这使得 queue.async 无能为力,这与开发人员的预期背道而驰。有没有办法在不使用演员的情况下序列化任务?
swift - SWIFTUI:从“(IndexSet)异步”类型的“异步”函数转换无效
我正在学习 SWIFTUI 并尝试做一些应用程序来测试我的知识,而无需真正遵循教程,因为我喜欢思考为什么事情会以某种方式工作。这就是我学习的方式:)
所以,我试图调用一个函数来通过 API 发布一些数据。该方法位于 ViewModel 内部。视图是一个列表,我需要能够触发 .OnDelete 修饰符才能通过视图模型触发 API 调用。
但我总是面临错误:
从 '(IndexSet) async -> Void' 类型的 'async' 函数到同步函数类型 '(IndexSet) -> Void' 的无效转换
这是代码。
在 ContentView.swift 中:
在 PostViewModel.swift 中:
我在这里做错了什么?
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 认为调用了错误的方法。