MainThreadPropertyAccessor

用于在 Task 中从主线程设置 ObservableObject 属性的语法糖。

Task {
    self.setOnMain.status = "Now I'll never get purple warnings again!"
}

安装

您可以使用 Swift Package Manager,方法是在您的 Package.swift 文件中将 MainThreadPropertyAccessor 声明为依赖项。

.package(url: "https://github.com/theisegeberg/MainThreadPropertyAccessor", from: "0.1.0")

有关更多信息,请参阅 Swift Package Manager 文档

问题

ObservableObject 通常用作 SwiftUI View 的一种控制器。在引入结构化并发(async/await)之后,我们经常需要在 ObservableObject 内部设置 @Published 属性的值。这意味着将代码包装在 DispatchQueue.main.async { ... } 中,或者使用 @MainActor 注解的方法。 这可以实现,但代码量很大。

解决方案

一个没有要求的协议,提供一个默认扩展,该扩展仅公开一个计算属性:.setOnMain。 这返回一个对象,可以基于实现该协议的 ObservableObjectKeyPath 进行下标访问。

用法

  1. 将协议 MainThreadPropertyAccessor 添加到您的 ObservableObject
  2. 使用 self.setOnMain.somePropertyOfYourObject = newValue 在您的 ObservableObject 上设置属性
class AnObservableObject: ObservableObject, MainThreadPropertyAccessor {
    @Published var status:String = ""
    func updateStatus() {
        Task {
            // Do some async work
            self.status = "Will update the UI from a background thread" // Warning!
            self.setOnMain.status = "Will update the UI from the main dispatch queue" // 😘
        }
    }
}