从后台线程获取 @Published 属性的值(不更改它)是正确的做法吗?

问题描述 投票:0回答:1

为了防止误解问题:我很清楚,不允许从后台线程为 @Published 属性发布

新值。 
但这不是我的问题。

我想知道从后台线程获取/读取@Published

属性的值(不更改它)是否可以
。如果没有,为什么?

例如:

class ViewModel: ObservableObject { @Published var name: String = "" func saveName() { DispatchQueue.global().async { print("Getting name from background: \(self.name)") // <-- HERE } } } struct ContentView: View { @StateObject var viewModel = ViewModel() var body: some View { VStack { TextField("Name", text: $viewModel.name) Button("Submit") { viewModel.saveName() } } } }
直觉上感觉不对,但是

    没有编译错误
  • 运行此类代码时不会出现运行时错误
  • 没有看到任何副作用,并且
  • 文档中没有具体说明这是错误的
这是一个有效的代码吗?

swift swiftui concurrency
1个回答
0
投票
你问:

这是一个有效的代码吗?

不,它不是线程安全的。显然,您没有做任何事情来体现非线程安全行为,但如果该属性是

@Published

,则可能您打算对其进行变异,从而体现出潜在的问题。

您注意到您收到了:

没有编译错误

如果您将“严格并发检查”构建设置设置为“完成”,则收到警告。

如果您将

ObservableObject

 与主要参与者隔离(按照 WWDC 2021 的视频
Discover concurrency in SwiftUI中的建议),您现在将收到有关从后台队列访问 name
 的警告,现在已与主要参与者隔离.

底线,如果您有一个属性被发布到 UI,最简单的方法是将该属性与主要参与者隔离,编译器将(至少使用“严格并发检查”的“完整”设置)警告您误用。

© www.soinside.com 2019 - 2024. All rights reserved.