【问题标题】:SwiftUI observe published object of published objectSwiftUI 观察已发布对象的已发布对象
【发布时间】:2022-01-04 18:30:02
【问题描述】:

点击按钮时,游戏中添加了一个玩家,我想通过视图模型观察游戏中的变化。当我按下按钮时,计数器不会改变。

就好像我需要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")
        }
    }
}

【问题讨论】:

    标签: swiftui combine


    【解决方案1】:

    您想在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()
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2019-02-24
      相关资源
      最近更新 更多