Есть ли способ вызвать assign () более одного раза в Swift Combine? - PullRequest
0 голосов
/ 30 марта 2020

Я хотел бы обновить некоторые переменные значениями, полученными при обработке вновь опубликованного значения. Например, учитывая:

class ProductViewModel: ObservableObject {
    @Published var PublishedX: Int = 0
    @Published var PublishedY: Int = 0
    @Published var PublishedProduct: Int = 0
    // ...
    init() {
        productPublisher = Publishers.CombineLatest(external.XPublisher, internal.YPublisher)
            // .assignAndContinue(\.PublishedX, \.PublishedY) // something like this
            .flatMap(MyPublishers.secretMultiplication)
            .assign(to: \.PublishedProduct, on: self)
     }
 }

Я хотел бы также присвоить новым значениям XPublisher и YPublisher переменные (соответственно, ОпубликованоX и ОпубликованоY).

Есть ли способ установить эти два переменных, а затем продолжить обработку события?

1 Ответ

0 голосов
/ 30 марта 2020

Нет встроенного варианта assign(to:on:), который возвращает другое Publisher вместо Cancellable.

Просто используйте несколько assign s:

class ProductViewModel: ObservableObject {
    @Published var PublishedX: Int = 0
    @Published var PublishedY: Int = 0
    @Published var PublishedProduct: Int = 0

    init() {
        external.XPublisher
            .assign(to: \.PublishedX, on: self)
            .store(in: &tickets)
        internal.YPublisher
            .assign(to: \.PublishedY, on: self)
            .store(in: &tickets)
        external.XPublisher
            .combineLatest(internal.YPublisher) { $0 * $1 }
            .assign(to: \.PublishedProduct, on: self)
            .store(in: &tickets)
    }

    private var tickets: [AnyCancellable] = []
}

Обратите внимание, что эти подписки создают циклы сохранения. Swift не сможет уничтожить экземпляр ProductViewModel, пока массив tickets не будет очищен. (Это не свойство моего предложения. Ваш исходный код также должен где-то хранить свою подписку, иначе она будет немедленно отменена.)

Кроме того, существование PublishedProduct сомнительно. Почему бы не просто вычисляемое свойство?

var product: Int { PublishedX * PublishedY }
...