【发布时间】:2021-12-16 04:41:39
【问题描述】:
我正在尝试使用 SwiftUI 和 Combine,并且希望能够在结构项目数组发生变化时接收通知(项目内的变化或数组的变化,即追加、删除)。
我尝试了以下代码,但给定一个包含三个元素的输入数组,我得到的只是这三个首字母中的每一个的 receiveValue,即使通过 UI 对数组进行更改(正确反映变化)。就好像它曾经的出版商着火了一样。
struct Item: Identifiable {
var id = UUID()
var title: String
}
class ItemStore: ObservableObject {
@Published var items: [Item]
private var cancellables = Set<AnyCancellable>()
init(items: [Item] = []) {
self.items = items
self.items.publisher
.sink(receiveValue: {
print("save=\($0)")
})
.store(in: &cancellables)
}
}
在玩了一些之后,我尝试了以下操作,然后它接收到一个包含整个数组的接收值,并且每次更新都会这样做。这实际上足以满足我当前的实验,但似乎不应该这样做,戳到 @Published 数组的内部。
struct Item: Identifiable {
var id = UUID()
var title: String
}
class ItemStore: ObservableObject {
@Published var items: [Item]
private var cancellables = Set<AnyCancellable>()
init(items: [Item] = []) {
self.items = items
self._items.projectedValue
.sink(receiveValue: {
print("save=\($0)")
})
.store(in: &cancellables)
}
}
我想问题的关键是,在应用程序的生命周期内接收通知的正确方法是:
- 一个数组
- 数组的元素
注意:我知道我可以使用 .dropFirst 方法抑制初始分配(可选地指定要跳过的元素数量)。
ItemStore 实例使用 environmentObject 传入并使用 @EnvironmentObject 访问。
我知道可能有更好的方法来响应持久状态的更改,但这对于一个简单的应用程序似乎仍然有效。
【问题讨论】:
-
“似乎不应该怎么做,戳到 @Published 数组的内部”——这是因为您正在使用
_合成变量进行访问吗?最常见的方法就是使用$items而不是_items.projectedValue -
@jnpdx 啊,是的,看不到!我想我一定是用了 $self ,这当然是行不通的,然后就忘记了我在做什么。非常感谢。
标签: swiftui combine publisher subscriber