问题标签 [swift5.5]

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 回答
377 浏览

swift - 错误:无法查找符号:Swift.Task.Handle 的名义类型描述符尝试使用 Xcode 12.5 beta / Swift 5.5 进行异步/等待

我试图弄清楚如何使用 Xcode 12.0 beta / Swift 5.5 在 Playground 中使用 async/await,但每次都会出错。

这是我的整个操场代码,这可能是错误的:

我收到此错误:

错误:无法查找符号:Swift.Task.Handle 的名义类型描述符

任何解决方案都会很棒!

0 投票
1 回答
1531 浏览

ios - 我可以在 Swift 中使用演员来始终调用主线程上的函数吗?

我最近看到 Swift 在Swift 5.5中引入了 Actor 模型的并发支持。当我们有一个共享的、可变的状态时,这个模型使安全的并发代码能够避免数据竞争。

我想避免我的应用程序 UI 中的主线程数据竞争。为此,DispatchQueue.main.async无论我设置UIImageView.image属性或UIButton样式,我都会在调用站点进行包装。

这似乎不安全,因为我必须记住在主队列上手动调度该方法。另一个解决方案如下所示:

但这看起来像很多样板文件,我不会说我喜欢将它用于具有不止一层嵌套的复杂函数。

对 Actors 的 Swift 支持的发布看起来是一个完美的解决方案。那么,有没有办法让我的代码更安全,即始终使用 Actors 在主线程上调用 UI 函数?

0 投票
4 回答
985 浏览

swift - 在 MainActor 调用后,asyncDetached 回到主线程

我正在尝试新的 async/await 东西。我的目标是test()在后台运行该方法,所以我使用Task.detached; 但是在test()我需要在主线程上进行调用时,所以我使用的是 MainActor。

(我意识到这可能看起来很复杂,但它从一个更好的现实世界案例中减少了。)

好的,所以测试代码看起来像这样(在视图控制器中):

第一个print说我不在主线程上。这就是我所期望的。

但第二个print说我主线程上。这不是我所期望的。

感觉好像我只是因为调用了一个 MainActor 函数而神秘地回到了主线程。我以为我会等待主线程,然后在我已经在的后台线程中恢复。

这是一个错误,还是我的期望错误?如果是后者,我如何期间跳出主线程,await然后又回到我所在的线程?我认为这正是 async/await 可以轻松实现的...?

(在某种程度上,我可以通过在调用Task.detached之后再次调用来“解决”这个问题getBounds;但那时我的代码看起来非常像嵌套的 GCD,我不得不怀疑我为什么要使用 async/await。)

也许我还为时过早,但我继续将此作为错误提交:https ://bugs.swift.org/browse/SR-14756 。


更多注释

我可以通过更换来解决问题

但这似乎是不必要的复杂,并不能说服我原来的现象不是错误。


我也可以通过使用演员来解决这个问题,这开始看起来是最好的方法。但同样,这并不能让我相信我在这里注意到的现象不是错误。


我越来越确信这是一个错误。我刚刚遇到(并报告)以下内容:

这打印howdy,然后第二个print打印true。但是如果我们注释掉第一个打印,剩下的(第二个)print打印false

仅仅添加或删除一条打印语句如何改变我们所在的线程?这当然不是故意的。

0 投票
1 回答
729 浏览

swift - Swift 5.5:逐行异步迭代文件

WWDC2021 28:00 的“Platforms State of the Union”视频中提到,

[Apple] 甚至增加了对逐行异步迭代文件的支持

在 macOS 12/iOS 15 和 Swift 5.5 的基础中。

什么是新 API,我现在如何通过文件异步逐行迭代?

0 投票
4 回答
3528 浏览

swift - 如何在 Swift 5.5 中等待来自同步函数的异步函数?

当遵守协议或重写超类方法时,您可能无法将方法更改为 be async,但您可能仍想调用一些async代码。例如,当我正在重写一个要根据 Swift 的新结构化并发编写的程序时,我想通过覆盖定义的 on 来在async测试套件的开头调用一些设置代码。我希望我的设置代码在任何测试运行之前完成,因此使用or是不合适的。class func setUp()XCTestCaseTask.detachedasync { ... }

最初,我写了一个这样的解决方案:

这似乎工作得很好。然而,在Swift 并发:在幕后,运行时工程师 Rokhini Prabhu 指出

信号量和条件变量等原语在 Swift 并发中使用是不安全的。这是因为它们对 Swift 运行时隐藏了依赖关系信息,但在代码的执行中引入了依赖关系……这违反了线程向前推进的运行时契约。

她还包括了这样一个不安全的代码模式的代码片段

这尤其是我想出的确切模式(我发现我想出的代码正是规范的不正确代码模重命名非常有趣)。

不幸的是,我无法找到任何其他方法来等待异步代码从同步函数完成。此外,我还没有找到任何方法来获取同步函数中异步函数的返回值。我在互联网上找到的唯一解决方案似乎和我的一样不正确,例如这篇The Swift Dev 文章

为了在同步方法中调用异步方法,您必须使用新的分离函数,并且您仍然必须使用调度 API 等待异步函数完成。

我认为这是不正确的或至少是不安全的。

什么是等待async同步函数中的函数与现有同步类或协议要求一起工作的正确、安全的方法,而不是特定于测试或 XCTest?或者,我在哪里可以找到说明Swift 中async/await与现有同步原语(如 )之间交互的文档DispatchSemaphore?它们永远不安全,还是我可以在特殊情况下使用它们?

更新:

根据@TallChuck 的回答,它注意到它setUp()总是在主线程上运行,我发现我可以通过调用任何@MainActor函数来故意死锁我的程序。这是应尽快更换我的解决方法的极好证据。

明确地说,这是一个挂起的测试。

@MainActor但是,如果被注释掉,它不会挂起。我担心的一个问题是,如果我调用库代码(Apple 或其他),@MainActor即使函数本身没有标记,也无法知道它是否最终会调用函数@MainActor

我的第二个担心是,即使没有@MainActor,我仍然不知道我能保证这是安全的。在我的电脑上,这挂起。

如果这不适合您,请尝试添加更多unsafeWaitFors. 我的开发虚拟机有 5 个核心,这是 6unsafeWaitFor秒。5对我来说很好。这与 GCD 明显不同。这是 GCD 中的一个等价物,它不会挂在我的机器上。

这很好,因为 GCD 很乐意生成比 CPU 更多的线程。因此,也许建议是“只使用与unsafeWaitForCPU 一样多的 s”,但如果是这种情况,我希望在某个地方看到 Apple 明确说明了这一点。在一个更复杂的程序中,我是否真的可以确定我的代码可以访问机器上的所有内核,或者我的程序的其他部分是否可能正在使用其他内核,因此请求的工作unsafeWaitFor将永远不会预定?

当然,我的问题中的示例是关于测试的,因此在这种情况下,很容易说“建议是什么并不重要:如果它有效,它就有效,如果它不起作用,那么测试失败,你会修复它,”但我的问题不仅仅是关于测试;这只是一个例子。

使用 GCD,我对自己能够在DispatchQueue不耗尽可用线程总数的情况下将异步代码与信号量(在我自己控制的,而不是主线程上)同步的能力充满信心。我希望能够在 Swift 5.5 中将async同步函数中的代码与async/同步。await

如果这样的事情是不可能的,我也会接受来自 Apple 的文档,其中详细说明了在哪些情况下我可以安全地使用unsafeWaitFor或类似的同步技术。

0 投票
1 回答
1214 浏览

swift - 什么决定了 Swift 5.5 任务初始化程序是否在主线程上运行?

这是我之前的asyncDetached 在 MainActor call 后退回到主线程的一种后续行动。

这是一个 iOS 视图控制器的完整代码:

这两个函数test1test2是相同的,并且是从同一个地方调用的。然而其中一个operation:在后台线程上运行其任务初始化函数,而另一个在主线程上运行。

是什么决定了这一点?我只能认为它与声明方法的位置有关。但它与声明方法的位置有什么关系?

0 投票
1 回答
2407 浏览

swift - 如何访问参与者隔离的属性?

我试图检查演员的行为。这是 Swift5.5 提供的新特性。

我用官方文档swift.org中的示例代码创建了一个游乐场:

但是我的编译器在这个例子中失败了:

错误

Swift 编译器错误:

'await' 在不支持并发的函数中

Actor 隔离属性 'max' 只能从 Actor 内部引用

那么如何访问参与者隔离的属性呢?

也许这是编译器或示例代码中的错误?

Xcode 版本 13.0 测试版 (13A5154h) Swift 版本 5.5

0 投票
1 回答
796 浏览

ios - 具有异步等待任务组的最大线程数

我的目的是了解 Swift 5.5 的 async-await 使用的“协作线程池”,以及任务组如何自动约束并发程度:考虑以下任务组代码,并行进行 32 次计算:

虽然我希望它会限制并发程度,但正如宣传的那样,我一次只能获得两个(!)并发任务。这比我预期的要受限制得多:

在此处输入图像描述

如果我使用旧的 GCD concurrentPerform...

...我一次得到 12 个,充分利用设备(我的 6 核 i9 MacBook Pro 上的 iOS 15 模拟器),同时避免线程爆炸:

在此处输入图像描述

(FWIW,这两个都在 Big Sur 上运行的 Xcode 13.0 beta 1 (13A5154h) 中进行了分析。请忽略这两个运行中各个“工作”的细微差异,因为所讨论的功能只是随机旋转; 关键观察是并发程度是我们所期望的。)

这个新的 async-await(和任务组)自动限制并行度非常好,但是 async-await 的协作线程池比我预期的要受限制得多。而且我认为无法调整该池的这些参数。我们如何才能更好地利用我们的硬件,同时仍然避免线程爆炸(不求助于非零信号量或操作队列等旧技术)?

0 投票
1 回答
152 浏览

swift - TaskGroup `async` vs. `spawn`

有谁知道,在新的 Swift东西中,TaskGroup和async/await之间有什么区别,或者它们是纯同义词吗?(如果它们是同义词,我更喜欢。看起来我们正在打开一个块,而这根本不是我们正在做的事情。)asyncspawnspawnasyncasync

https://developer.apple.com/documentation/swift/taskgroup/3814850-async

https://developer.apple.com/documentation/swift/taskgroup/3814884-spawn

0 投票
2 回答
1575 浏览

swift - 带有 async/await 的 Swift Playground “在范围内找不到‘async’”

我正在尝试在 Xcode Playground 上运行这个异步函数:

我收到此错误消息:

所以我尝试在我的 func 调用中创建 am async 块:

然后我收到了这个错误信息:

我试图用新的 @MainActor 属性注释我的函数,但它不起作用。

我做错了什么?