【问题标题】:SwiftUI/Combine: Subscribing to array updates vs element updatesSwiftUI/Combine:订阅数组更新与元素更新
【发布时间】: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)
    }

}

我想问题的关键是,在应用程序的生命周期内接收通知的正确方法是:

  1. 一个数组
  2. 数组的元素

注意:我知道我可以使用 .dropFirst 方法抑制初始分配(可选地指定要跳过的元素数量)。

ItemStore 实例使用 environmentObject 传入并使用 @EnvironmentObject 访问。

我知道可能有更好的方法来响应持久状态的更改,但这对于一个简单的应用程序似乎仍然有效。

【问题讨论】:

  • “似乎不应该怎么做,戳到 @Published 数组的内部”——这是因为您正在使用 _ 合成变量进行访问吗?最常见的方法就是使用$items 而不是_items.projectedValue
  • @jnpdx 啊,是的,看不到!我想我一定是用了 $self ,这当然是行不通的,然后就忘记了我在做什么。非常感谢。

标签: swiftui combine publisher subscriber


【解决方案1】:

根据@jnpdx 的评论,我在items 之前缺少$,所以正确的用法应该是

self.$items.sink(...

【讨论】:

    猜你喜欢
    • 2021-01-17
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 2020-12-19
    • 2021-01-07
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    相关资源
    最近更新 更多