【发布时间】:2021-08-03 11:39:00
【问题描述】:
我做了一个简单的 Playground 示例,试图弄清楚如何使用 SwiftUI 和 Combine 将 View Model 连接到 View。 我相信我已经按书完成了(检查下面的代码示例),但是当我点击“增量”按钮时,此打印出现在控制台中:
=== AttributeGraph: cycle detected through attribute 22736 ===
=== AttributeGraph: cycle detected through attribute 18320 ===
=== AttributeGraph: cycle detected through attribute 17200 ===
=== AttributeGraph: cycle detected through attribute 18320 ===
=== AttributeGraph: cycle detected through attribute 21592 ===
=== AttributeGraph: cycle detected through attribute 21592 ===
=== AttributeGraph: cycle detected through attribute 21768 ===
=== AttributeGraph: cycle detected through attribute 21768 ===
=== AttributeGraph: cycle detected through attribute 18152 ===
=== AttributeGraph: cycle detected through attribute 21768 ===
=== AttributeGraph: cycle detected through attribute 20224 ===
=== AttributeGraph: cycle detected through attribute 18152 ===
=== AttributeGraph: cycle detected through attribute 18152 ===
=== AttributeGraph: cycle detected through attribute 18280 ===
=== AttributeGraph: cycle detected through attribute 22568 ===
=== AttributeGraph: cycle detected through attribute 22568 ===
=== AttributeGraph: cycle detected through attribute 22736 ===
=== AttributeGraph: cycle detected through attribute 22568 ===
=== AttributeGraph: cycle detected through attribute 22736 ===
=== AttributeGraph: cycle detected through attribute 22568 ===
在那之后,我开始试验代码并发现延迟调用 View Model 的增量方法可以解决这个问题。 (取消注释示例中的注释行以对此进行测试。) 现在困扰我的是,我不知道为什么会出现这个警告,也不知道为什么延迟方法调用会修复它。
如果有人能解释幕后发生的事情以及为什么会发生这种情况,我将不胜感激。
环境:
macOS Big Sur Version 11.4
Xcode Version 12.5.1 (12E507)
示例代码:
import Combine
import SwiftUI
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
class ViewModel: ObservableObject {
@Published private (set) var counter: Int = 0
func increment() {
counter += 1
}
}
struct SomeView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack(alignment: .center, spacing: 8) {
Text("Counter: \(viewModel.counter)")
.padding()
Button("Increment") {
// uncomment to fix AttributeGraph cycle warning
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.001) {
self.viewModel.increment()
// }
}
.padding()
}
.padding()
}
}
let viewModel = ViewModel()
let view = SomeView(viewModel: viewModel)
PlaygroundPage.current.setLiveView(view)
【问题讨论】:
-
这不会发生在 xcode 或 iPhone 中。
标签: swiftui combine observableobject observedobject