我有一个应用程序,可以对给定的字符串进行一些处理,这在 2Task秒内完成。在此期间我正在显示动画。当这些Task完成后,我需要隐藏动画。下面的代码可以工作,但看起来不太好。我相信有更好的方法来做到这一点?
let firTask = Task {
/* Slow-running code */
}
let airportTask = Task {
/* Even more slow-running code */
}
Task {
_ = await firTask.result
_ = await airportTask.result
self.isVerifyingRoute = false
}
Run Code Online (Sandbox Code Playgroud) 我需要在我创建的任务中使用我自己的自定义错误枚举:
enum MyError: Error {
case someError
}
var myTask: Task<MyModel, MyError> = Task { () throws -> MyModel in
// in case of an error:
// throw .someError
// ... perform some work
return MyModel()
}
Run Code Online (Sandbox Code Playgroud)
但我在任务初始化程序的开头收到以下错误:
Referencing initializer 'init(priority:operation:)' on 'Task' requires the types 'MyError' and 'Error' be equivalent。
如何限制Task只抛出属于我的自定义错误类型的错误MyError?
我是 Swift 并发的新手(我想像大多数人一样),我遇到了编译器错误,我不知道该怎么办。
struct Thing {
var counter = 0
mutating func increment() async {
counter += 1
}
}
class Controller: UIViewController {
var thing = Thing()
func mutate() async {
await thing.increment()
print(thing.counter)
}
}
let c = Controller()
Task {
await c.mutate()
}
Run Code Online (Sandbox Code Playgroud)
该mutate()函数的第一行给出了以下错误。
Actor-isolated property 'thing' cannot be passed 'inout' to 'async' function call
如果我只是继承class而不是UIViewController事情工作正常,但我需要这里的控制器,所以我需要弄清楚如何使其在特定的上下文中工作。
我知道异步 SwiftTask不应该阻塞(异步工作线程必须始终向前推进)。如果我有一个 100% 异步 Swift 应用程序,但需要引入一些阻塞任务,那么正确的方法是什么,不会阻塞任何 swift 异步线程池工作线程?
我假设需要异步线程池之外的新专用线程,如果该假设正确,异步函数等待该线程完成的线程安全方法是什么?我可以使用 的主体withCheckedContinuation来启动线程,将continuation句柄复制到该线程中并continuation.resume在线程完成时从该线程调用吗?
我AuthorizationRequester可以同时从许多地方调用它,但只有第一个调用可以运行requestAuthorizationFromUser()(并等待几十秒的用户交互) - 其余的这些调用应该await是来自 的结果requestAuthorizationFromUser(),但不能直接调用它。
看代码:
actor AuthorizationRequester {
enum SimpleResult {
case success, failure
}
typealias ResultCompletion = (SimpleResult) -> ()
private var requestInProgress = false
private var requestCompletions = [ResultCompletion]()
func request(completion: @escaping ResultCompletion) async {
requestCompletions.append(completion)
guard !requestInProgress else { return }
requestInProgress = true
let result = await requestAuthorizationFromUser()
requestCompletions.forEach { $0(result) }
requestCompletions.removeAll()
requestInProgress = false
}
private func requestAuthorizationFromUser() async -> SimpleResult {
// ...some code
} …Run Code Online (Sandbox Code Playgroud) 我正在快速尝试新的异步/等待模式,但遇到了一些让我感到困惑的事情。
\nstruct ContentView: View {\n var body: some View {\n Text("Hello World!")\n .task {\n var num = 1\n\n Task {\n print(num)\n }\n\n Task {\n print(num)\n }\n }\n }\n\n func printScore() async {\n var score = 1\n\n Task { print(score) }\n Task { print(score) }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n有人可以澄清一下上面的屏幕截图,为什么编译器只抱怨捕获的var内部函数,而在使用结构体的计算属性上的修饰符printScore() 执行相同操作时不抱怨(即第 14-24 行)?taskbodyContentView
这是我提出的示例,并对编译器行为感到困惑。我还将编译器设置“严格并发检查\xe2\x80\x9d 构建设置”更改为\xe2\x80\x9cComplete\xe2\x80\x9d,但仍然不这样做没有看到编译器抱怨。
\n我正在注释我的函数,@MainActor以确保可以从任何异步位置安全地调用它以触发 UI 更新。尽管如此,我还是遇到了一个错误,不知何故,UI 更新似乎是在后台线程上尝试的,即使(据我理解)该函数严格绑定到`@MainActor\xc2\xb4.
这是我的代码:
\n/// Dismisses the popup from its presenting view controller.\n@MainActor public func dismiss() {\n presentingViewController?.dismiss(self)\n}\nRun Code Online (Sandbox Code Playgroud)\n它是从 an 内部调用的,NSViewController它使用 监听某个事件NotificationCenter,然后在以下objc函数中启动解雇:
class MainWindowControllerVC: NSWindowController, NSWindowDelegate {\n override func windowDidLoad() {\n NotificationCenter.default.addObserver(self, selector: #selector(self.dismissVCastSharePopup), name: .NOTIF_DISMISS_POPUP, object: nil)\n }\n\n @objc private func dismissPopup() {\n // some other cleanup is happening here\n popup?.dismiss()\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n我收到以下错误:
\n*** Terminating app due to uncaught exception \'NSInternalInconsistencyException\', reason: \'NSWindow drag …Run Code Online (Sandbox Code Playgroud) 我正在学习 SWIFTUI 并尝试制作一些应用程序来测试我的知识,而无需实际遵循教程,因为我喜欢思考为什么事情会以某种方式工作。这就是我学习的方式:)
因此,我尝试调用一个函数来通过 API 发布一些数据。该方法位于 ViewModel 内部。视图是一个列表,我需要能够触发 .OnDelete 修饰符以通过视图模型触发 API 调用。
但我总是面临这样的错误:
从“(IndexSet) async -> Void”类型的“async”函数到同步函数类型“(IndexSet) -> Void”的转换无效
这是代码。
在 ContentView.swift 中:
// there is a @State var res = PostsViewModel() above the body!
List {
ForEach(res.posts, id:\.self){ item in
VStack {
Text(item.title)
.font(.headline)
Text("\(item.content) <> \(item._id)")
}
}
.onDelete{ IndexSet in
var index: Int = -1
for idx in IndexSet {
index = idx
}
print("index ix \(index)")
await res.updateData(at: index)
}
}
Run Code Online (Sandbox Code Playgroud)
在 PostViewModel.swift 中:
func updateData(at …Run Code Online (Sandbox Code Playgroud) 我正在尝试思考如何将 Swift 并发性与使用基于块的东西(如 Timer)的旧代码集成。因此,当我构建下面的代码时,编译器告诉我self.handleTimer()该行Expression is 'async' but is not marked with 'await'
为什么是异步的?它没有被标记async并且没有做任何事情。当我在没有计时器的情况下调用它时,我不需要await. 参与者隔离是否意味着对成员的每次调用都是来自该上下文之外的“异步”?
@MainActor
class MyClass {
func startTimer() {
_ = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
Task {
self.handleTimer() // "Expression is 'async' but is not marked with 'await'"
}
}
}
func handleTimer() {
}
}
Run Code Online (Sandbox Code Playgroud) 我围绕 PassthroughSubject 创建了一个小包装器,将其转换为 AsyncStream。
protocol Channelable {}
final class Channel {
private let subject = PassthroughSubject<Channelable, Never>()
func send(_ value: Channelable) {
subject.send(value)
}
func getValues() -> AsyncStream<Channelable> {
AsyncStream { continuation in
let task = Task {
for await value in subject.values {
continuation.yield(value)
}
}
continuation.onTermination = { _ in
task.cancel()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我执行以下操作时:
enum Action: Channelable {
case execute
}
func test() async {
let channel = Channel()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
channel.send(Action.execute)
channel.send(Action.execute) …Run Code Online (Sandbox Code Playgroud)