如何使用发布主题来观察变量的值?

How to use a Publish subject to observe a variable's value?

我是使用 RxSwift 框架的新手,我实际上正在学习并试图理解基础知识,我希望得到您的帮助。

private func observeCurrentIndex() -> Observable<Int> {
    return Observable<Int>.create { (observer) -> Disposable in
      observer.onNext(self.currentIndex)
      return Disposables.create()
    }
  }

这里我在 currentIndex 上创建了一个 observable,它是一个 int。当我订阅它时,我只得到 currentIndex 的第一个值,即 2。它不应该在 currentIndex 更改时通知我(就像 KVO 一样)吗?

override func viewDidLoad() {
    super.viewDidLoad()
    observeCurrentIndex()
      .subscribe(onNext: { (valeur) in
        print("new value \(valeur)")
      })
      .addDisposableTo(disposeBag)
  }

为了在每次 currentIndex 更改值时得到通知,我被告知必须为此使用 publishSubject。

@IBAction func increaseAction(_ sender: UIButton) {
    if currentIndex <= kMaxIndex {
      currentIndex = currentIndex + 1
    }
  }

有人可以告诉我在哪里以及如何做吗?提前致谢。

我来自 RxJS,但我认为你真正需要的是 ReplaySubject

您提供的第一个代码,您只是在创建一个只有 returns 1 个值的可观察对象。 Observable.create 中的代码每次有人 .subscribe() 时都会执行一次。

发布更意味着在许多订阅者之间共享订阅...最完美的情况是,如果您需要从一台服务器收集的特定信息在您的应用程序的许多地方使用...您不想用这么多请求向服务器发送垃圾邮件,所以您只需发出一个请求,发布该请求,观察者就会订阅该已发布的流。

一个ReplaySubject(或者BehaviourSubject,但是你需要在初始化的时候知道初始值)更符合你的要求:它既是一个Observable又是一个Observer,一个其他观察者可以订阅的对象到,并且每次您调用 .onNext() 时,所有订阅者都会获得一个新值。

Rx 不会变魔术,它不知道 when/how 你正在编辑你的变量。因此,您需要在对象中创建长度为 1 的 ReplaySubject,并为订阅者创建长度为 return 的对象。然后在您的 currentIndex 更改时跟踪您的代码,调用该 ReplaySubject 上的 onNext 方法。

通常,Subject 用于将命令式 API 连接到响应式世界。有关如何使用主题的更多信息,请参见 here

有几个解决方案可以使用 RxSwift 的原语观察变量的演化

使用 KVO

class WithIndex: NSObject {
  dynamic var currentIndex: Int

  func observeCurrentIndex() -> Observable<Int> {
    return instance.rx.observe(Int.self, "currentIndex")
  }

  @IBAction func increaseAction(_ sender: UIButton) {
    if currentIndex <= kMaxIndex {
      currentIndex = currentIndex + 1
    }
  }
}

此解决方案的缺点是 WithIndex 需要继承 NSObject 才能使 KVO 可用。

使用变量

class WithIndex {
  let currentIndex: Variable<Int>

  func observeCurrentIndex() -> Observable<Int> {
    return currentIndex.asObservable()
  }

  @IBAction func increaseAction(_ sender: UIButton) {
    if currentIndex.value <= kMaxIndex {
      currentIndex.value = currentIndex.value + 1
    }
  }
}

这个比较实用。然后,您可以使用 currentIndex.value = 12 设置 currentIndex 的值,并使用 currentIndex.asObservable().subscribe(...).

进行观察

Variable is a simple wrapper 大约 BehaviorSubject 并且每次变量值更改时都会发送一个 .next 事件。