Swift观察动态字典
Swift Observe dynamic dictionary
我正在尝试使用 @Published
监听字典中元素的变化。
我有一本字典,包含玩家分数列表,由玩家 ID 索引。
它看起来像这样:
class PlayersScore: ObservableObject {
@Published var scores: [String: PlayerScore] = [:];
}
此字典通过名为 Api
的 class 共享实例的 属性 scores
公开。
class Api: NSObject {
static var shared = Api()
@Published public var scores = PlayersScore()
func updatePlayerScore(playerId: String, score: PlayerScore) {
this.scores.scores[playerId] = score
}
}
有时,玩家的分数会更新。
我有一个专用于 Player 的视图,如下所示:
struct PlayerView: View {
var player: Player
@ObservedObject private var scores = Api.shared.scores
var body: some View {
HStack {
Text(player.name)
Text("Latest score: \(scores.scores[player.id] ?? "not found")")
}
}
}
当玩家的分数更新时,我的视图会重新渲染。
我的问题是......当玩家分数更新时,所有玩家的视图都会重新呈现,因为他们都会对主字典的变化做出反应。
所以,我想在他的相应视图中订阅特定玩家得分的变化,因此只有适当的视图在必要时重新呈现。
订阅或访问时玩家分数可能尚未初始化(即 scores.scores[player.id]
可能尚不存在)。
知道如何实现吗?
谢谢!
这里有一个可行的方法——让PlayerScore
成为可观察的class,这样PlayersScore只会在新玩家加入时更新,并且由于观察到特定的PlayerScore
明确只对应视图将根据 value
更改进行更新。
class PlayerScore: ObservableObject {
var id: String // say back ref to user
@Published var value: Int
// ... other published properties
}
struct PlayerView: View {
var player: Player
@ObservedObject private var scores = Api.shared.scores
var body: some View {
HStack {
Text(player.name)
if let score = scores.scores[player.id] {
PlayerScoreView(playerScore: score)
} else {
Text("No scores")
}
}
}
}
struct PlayerScoreView: View {
@ObservedObject var playerScore: PlayerScore
var body: some View {
Text("Latest score: \(playerScore.value)")
}
}
注意:这只是此处编码的草图,因此可能有错别字
我正在尝试使用 @Published
监听字典中元素的变化。
我有一本字典,包含玩家分数列表,由玩家 ID 索引。 它看起来像这样:
class PlayersScore: ObservableObject {
@Published var scores: [String: PlayerScore] = [:];
}
此字典通过名为 Api
的 class 共享实例的 属性 scores
公开。
class Api: NSObject {
static var shared = Api()
@Published public var scores = PlayersScore()
func updatePlayerScore(playerId: String, score: PlayerScore) {
this.scores.scores[playerId] = score
}
}
有时,玩家的分数会更新。
我有一个专用于 Player 的视图,如下所示:
struct PlayerView: View {
var player: Player
@ObservedObject private var scores = Api.shared.scores
var body: some View {
HStack {
Text(player.name)
Text("Latest score: \(scores.scores[player.id] ?? "not found")")
}
}
}
当玩家的分数更新时,我的视图会重新渲染。
我的问题是......当玩家分数更新时,所有玩家的视图都会重新呈现,因为他们都会对主字典的变化做出反应。
所以,我想在他的相应视图中订阅特定玩家得分的变化,因此只有适当的视图在必要时重新呈现。
订阅或访问时玩家分数可能尚未初始化(即 scores.scores[player.id]
可能尚不存在)。
知道如何实现吗?
谢谢!
这里有一个可行的方法——让PlayerScore
成为可观察的class,这样PlayersScore只会在新玩家加入时更新,并且由于观察到特定的PlayerScore
明确只对应视图将根据 value
更改进行更新。
class PlayerScore: ObservableObject {
var id: String // say back ref to user
@Published var value: Int
// ... other published properties
}
struct PlayerView: View {
var player: Player
@ObservedObject private var scores = Api.shared.scores
var body: some View {
HStack {
Text(player.name)
if let score = scores.scores[player.id] {
PlayerScoreView(playerScore: score)
} else {
Text("No scores")
}
}
}
}
struct PlayerScoreView: View {
@ObservedObject var playerScore: PlayerScore
var body: some View {
Text("Latest score: \(playerScore.value)")
}
}
注意:这只是此处编码的草图,因此可能有错别字