【发布时间】:2020-03-22 15:51:36
【问题描述】:
我得到一个无限循环,当使用带有@Published 变量的协议时,onReceive 被无限调用。要在协议中使用@Published 变量,我正在使用这个stackoverflow answer。 MyImageView 中的这一行:
if self.viewModel.answered {
似乎在
中引起了呼叫onReceive { self.viewModel.objectWillChange
在 ContentView 内。
知道如何进行这项工作吗?
这是完整的代码:
环境对象:
import UIKit
import SwiftUI
import Combine
import Foundation
protocol MyProtocol: AnyObject {
var answered: Bool { get set }
var answeredPublished: Published<Bool> { get }
var answeredPublisher: Published<Bool>.Publisher { get }
}
class GameViewModel: ObservableObject & MyProtocol {
@Published var answered = false
var answeredPublished: Published<Bool> { _answered }
var answeredPublisher: Published<Bool>.Publisher { $answered }
}
观看次数:
import SwiftUI
struct MyImageView: View {
@EnvironmentObject var viewModel: GameViewModel
var body: some View {
if self.viewModel.answered {
print("not nil")
return AnyView(Image("clearImage")
.resizable()
.scaledToFit()
)
}
else {
print("nil")
return AnyView(
Text(self.viewModel.answered ? "true" : "false")
)
}
}
}
struct ViewBelow<ViewModel: ObservableObject & MyProtocol>: View {
@EnvironmentObject var viewModel: ViewModel
var body: some View {
Text("below")
.onReceive(self.viewModel.objectWillChange,
perform: { _ in
print("onReceive target")
}
)
}
}
struct ContentView: View {
@EnvironmentObject var viewModel: GameViewModel
var body: some View {
GeometryReader {
geo in
VStack {
MyImageView()
ViewBelow<GameViewModel>()
}
}
}
}
场景委托 导入 UIKit 导入 SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView().environmentObject(GameViewModel())
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
}
【问题讨论】:
-
不,不是。使用 Xcode 11.4 / iOS 13.4 测试 - 按预期工作。我刚刚将
.onTapGesture添加到MyImageView()以测试answered的变化。 -
MyProtocol 背后的理念是什么?我有点迷路了……
-
@user3441734 : 我已经更新了视图代码,现在协议背后的原因应该更清楚了。
-
@Asperi :我正在使用 XCode 11.3.1 和 iPhone 8 模拟器 (13.3),我得到了无限循环。你能用更新后的代码进行验证吗?