标签: mainactor

SwiftUI @MainActor 失去全球演员

从我的角度来看,我正在调用一个ObservableObject@StateObject。该类内部有一个函数,整个类都被标记为@MainActor。在我看来,有一个TextFieldwithonChange修饰符,可以通过 执行调用该函数viewModel.funcname

Xcode is complaining with an error of:

Converting function value of type '@MainActor (String) -> Void' to '(String) -> Void' loses global actor 'MainActor'
Run Code Online (Sandbox Code Playgroud)

I've been researching this for hours now and have found little to nothing. Even Apple's own docs say to simply use await but that doesn't work, at least not the many ways I've tried it.

This is the code within my view: …

concurrency multithreading swiftui mainactor

11
推荐指数
1
解决办法
7706
查看次数

在 MainActor 调用后 asyncDetached 回退到主线程

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

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

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

override func viewDidLoad() {
    super.viewDidLoad()
    asyncDetached(priority: .userInitiated) {
        await self.test()
    }
}
@MainActor func getBounds() async -> CGRect {
    let bounds = self.view.bounds
    return bounds
}
func test() async {
    print("test 1", Thread.isMainThread) // false
    let bounds = await self.getBounds()
    print("test 2", Thread.isMainThread) // true
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

这是一个错误,还是我的期望错了?如果是后者,怎么我时走出主线程await,但再回来线程我是吗?我认为这正是 async/await 可以简化的事情......?

(在某种程度上,我可以通过在调用 …

async-await swift swift5.5 mainactor

8
推荐指数
3
解决办法
314
查看次数

使用 Swift async、await、@MainActor 的后台任务的最佳解决方案是什么

我\xe2\x80\x99m 正在学习Swift asyncawait、 。@MainActor

\n

我想运行一个很长的过程并显示进度。

\n
import SwiftUI\n\n@MainActor\nfinal class ViewModel: ObservableObject {\n    @Published var count = 0\n\n    func countUpAsync() async {\n        print("countUpAsync() isMain=\\(Thread.isMainThread)")\n        for _ in 0..<5 {\n            count += 1\n            Thread.sleep(forTimeInterval: 0.5)\n        }\n    }\n\n    func countUp() {\n        print("countUp() isMain=\\(Thread.isMainThread)")\n        for _ in 0..<5 {\n            self.count += 1\n            Thread.sleep(forTimeInterval: 0.5)\n        }\n    }\n}\n\nstruct ContentView: View {\n    @StateObject private var viewModel = ViewModel()\n\n    var body: some View {\n        VStack {\n            Text("Count=\\(viewModel.count)")\n                .font(.title)\n\n            Button("Start Dispatch") {\n                DispatchQueue.global().async {\n …
Run Code Online (Sandbox Code Playgroud)

asynchronous async-await swift mainactor

8
推荐指数
1
解决办法
9404
查看次数

如何为 XCTest、SwiftUI 预览等初始化注释为 @MainActor 的 Swift 类

我们希望在现有的 SwiftUI 项目中使用@MainActorViewModel 的注释,这样我们就可以摆脱DispatchQueue.main.async.receive(on: RunLoop.main)

@MainActor
class MyViewModel: ObservableObject {
    private var counter: Int
    init(counter: Int) {
        self.counter = counter
    }
}
Run Code Online (Sandbox Code Playgroud)

从 SwiftUI 视图初始化带注释的类时,这种方法效果很好。但是,当使用 SwiftUI Previews 或 XCTest 时,我们还需要从上下文外部初始化该类@MainActor

class MyViewModelTests: XCTestCase {

    private var myViewModel: MyViewModel!
    
    override func setUp() {
        myViewModel = MyViewModel(counter: 0)
    }
Run Code Online (Sandbox Code Playgroud)

这显然不能编译:

主要参与者隔离属性“init(counter:Int)”无法从非隔离上下文中进行变异

现在,显然我们也可以按照此处的建议MyViewModelTests进行注释。@MainActor

但我们不希望所有的单元测试都在主线程上运行。那么在这种情况下推荐的做法是什么?

如果我们不想在初始化器中设置变量的值,则按照上面对话中建议的init方式注释函数才有效。nonisolated

ios async-await swift swiftui mainactor

6
推荐指数
2
解决办法
1280
查看次数

在调用声明为 @MainActor 的异步函数的任务中使用 @MainActor

我想了解是否需要考虑以下代码块将任务本身声明为 MainActor。

func login() {
    Task { [weak self] in
        let result = await self?.loginService.start()

        if result == .successful {
            self?.showWelcomeMessage() // updating the UI here
        }
    }
}

final class LoginService {

    @MainActor
    func start() async -> LoginResult {
        // Doing some UI related operations here
    }
}

Run Code Online (Sandbox Code Playgroud)

当任务内部调用的异步函数已经声明为 MainActor 时,我是否还需要将任务本身声明为 MainActor ?像这样:

func login() {
    Task { @MainActor [weak self] in
        let result = await self?.loginService.start()

        if result == .successful {
            self?.showWelcomeMessage() // updating the UI here
        } …
Run Code Online (Sandbox Code Playgroud)

ios async-await swift mainactor swift-concurrency

5
推荐指数
1
解决办法
1886
查看次数

@MainActor 类是对主要参与者的扩展吗?

如果正在上课@MainActor

@MainActor class MyClass : NSObject
{
}
Run Code Online (Sandbox Code Playgroud)

这是否也将其所有扩展都打开了@MainActor

extension MyClass
{
}
Run Code Online (Sandbox Code Playgroud)

concurrency ios swift mainactor

3
推荐指数
1
解决办法
540
查看次数