Nic*_*ner 6 ios async-await swift swiftui mainactor
我们希望在现有的 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
override func setUp() async throws使用@MainActor
class MyViewModel: ObservableObject {
var counter: Int
init(counter: Int) {
self.counter = counter
}
func set(counter: Int) {
self.counter = counter
}
}
Run Code Online (Sandbox Code Playgroud)
import XCTest
@testable import Demo
final class MyViewModelTests: XCTestCase {
private var myViewModel: MyViewModel!
override func setUp() async throws {
myViewModel = await MyViewModel(counter: 10)
}
override func tearDown() async throws {
myViewModel = nil
}
func testExample() async throws {
await myViewModel.set(counter: 20)
}
}
Run Code Online (Sandbox Code Playgroud)
只需标记setUp()为@MainActor
class MyViewModelTests: XCTestCase {
private var myViewModel: MyViewModel!
@MainActor override func setUp() {
myViewModel = MyViewModel(counter: 0)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1280 次 |
| 最近记录: |