SwiftUI 观察已发布对象的已发布对象
SwiftUI observe published object of published object
当按下按钮时,一个玩家被添加到游戏中,我想通过视图模型观察游戏中的变化。当我按下按钮时,计数器没有改变。
就好像我需要 ContentViewModel
中的游戏既是 @ObservedObject
又是 @Published
。
有人可以帮助我了解为什么设置错误的基本原理以及如何解决它吗?
import SwiftUI
import Combine
class Game: ObservableObject {
@Published var players: [String] = []
func addPlayer(_ player: String) {
players.append(player)
}
}
class ContentViewModel: ObservableObject {
@Published var game: Game {
didSet {
subscription = game.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}
}
}
var subscription: AnyCancellable?
init(game: Game) {
self.game = game
}
}
struct ContentView: View {
@ObservedObject var viewModel: ContentViewModel
var body: some View {
Text("Num players: \(viewModel.game.players.count)")
.padding()
Button("Add player") {
viewModel.game.addPlayer("player")
}
}
}
您想在 init
中设置 subscription
。这将确保每次 game
对象实例更改时,您也会触发 ContentViewModel
更改。
您的代码不起作用,因为只有对象 instance 在发生变化,而不是对象 reference。所以 game
不会触发 didSet
,因此你永远不会设置 subscription
.
代码:
class ContentViewModel: ObservableObject {
@Published var game: Game
var subscription: AnyCancellable?
init(game: Game) {
self.game = game
subscription = game.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}
}
}
当按下按钮时,一个玩家被添加到游戏中,我想通过视图模型观察游戏中的变化。当我按下按钮时,计数器没有改变。
就好像我需要 ContentViewModel
中的游戏既是 @ObservedObject
又是 @Published
。
有人可以帮助我了解为什么设置错误的基本原理以及如何解决它吗?
import SwiftUI
import Combine
class Game: ObservableObject {
@Published var players: [String] = []
func addPlayer(_ player: String) {
players.append(player)
}
}
class ContentViewModel: ObservableObject {
@Published var game: Game {
didSet {
subscription = game.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}
}
}
var subscription: AnyCancellable?
init(game: Game) {
self.game = game
}
}
struct ContentView: View {
@ObservedObject var viewModel: ContentViewModel
var body: some View {
Text("Num players: \(viewModel.game.players.count)")
.padding()
Button("Add player") {
viewModel.game.addPlayer("player")
}
}
}
您想在 init
中设置 subscription
。这将确保每次 game
对象实例更改时,您也会触发 ContentViewModel
更改。
您的代码不起作用,因为只有对象 instance 在发生变化,而不是对象 reference。所以 game
不会触发 didSet
,因此你永远不会设置 subscription
.
代码:
class ContentViewModel: ObservableObject {
@Published var game: Game
var subscription: AnyCancellable?
init(game: Game) {
self.game = game
subscription = game.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}
}
}