Swift-使用Combine的可变数据模型-更新订户

时间:2019-09-12 18:59:33

标签: swift combine

我有一个由PersonsCoins组成的模型。每个硬币都有一个所有者。

说我有一个personA拥有的硬币。我想跟踪硬币本身的变化,也要跟踪拥有该硬币的人的变化。我找到了使用包装器类Observable<Value>来完成此操作的好方法,该类仅将CurrentValueSubject<Value, Never>添加到任何对象(请参见下面的完整示例)。

基本上,我的模型具有跟踪所有硬币的数组[Observable<Coin>],我可以订阅硬币的观察者(发布者)以跟踪硬币属性的变化。

类似地,硬币的owner属性是一种Observable<Person>类型,我可以订阅该属性以跟踪所有者的更改。

订阅如下:

// coinObservable is a Observable<Coin> instance
let subscriber: AnyCancellable = coinObservable
    .observer

    // Get the owner's observer/publisher
    .flatMap({ $0.owner.observer })

    // And print the name (or do something else with it
    .sink { (person) in
        print()
}

这很好。但是,我希望能够更改硬币的所有者。但是,一旦我将owner属性更改为其他人,上述订阅将不再按预期工作。

我需要以某种方式将该订阅转移到新所有者的发布者,以便它现在可以跟踪新所有者。

我可以完全取消订阅,并与新的所有者创建一个新的订阅,但是我希望只要所有者更改,订阅就会自动发生。它应该在硬币结构之类的方法changeOwner(to:)中发生。

有人知道怎么做吗? 谢谢!

import UIKit
import Combine


/// Modified for Combine from `https://www.swiftbysundell.com/articles/handling-mutable-models-in-swift/`
class Observable<Value> {
    public var observer: CurrentValueSubject<Value, Never>
    private var value: Value

    init(value: Value) {
        self.value = value
        self.observer = CurrentValueSubject(value)
    }

    func update(with value: Value) {
        self.value = value
        observer.send(value)
    }

}


struct Person {
    let name: String
}

struct Coin {
    var owner: Observable<Person>
}


class Model {
    public private(set) var coins: [Observable<Coin>]
    public private(set) var persons: [Observable<Person>]

    init() {
        self.coins = []
        self.persons = []
    }

    public func add(_ coin: Coin) -> Observable<Coin> {
        let observable = Observable(value: coin)
        coins.append(observable)
        return observable
    }

    public func add(_ person: Person) -> Observable<Person> {
        let observable = Observable(value: person)
        persons.append(observable)
        return observable
    }
}

let model = Model()

// Create persons
let personA = Person(name: "Person A")
let personB = Person(name: "Person B")

// Add persons to the model
[personA, personB].forEach { model.add($0) }

// Add coin
let personAObservable = model.persons[0]
let coin = Coin(owner: personAObservable)
model.add(coin)

// Now grab the added coin observable and subscribe to the publisher
let coinObservable = model.coins[0]

let subscriber: AnyCancellable = coinObservable
    .observer

    // Now map to the owner's observer
    .flatMap({ $0.owner.observer })

    // And print the name
    .sink { (person) in
        print("name")
}

// Now I want to change the coin's owner to personB. How do I do that without losing the subscription of the coin that

0 个答案:

没有答案