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

时间:2017-01-25 10:50:35

标签: swift reactive-programming observable publish-subscribe rx-swift

我是使用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
    }
  }

有人可以告诉我在哪里以及如何做到这一点?提前谢谢。

2 个答案:

答案 0 :(得分:2)

通常,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设置currentIndex.value = 12的值,并使用currentIndex.asObservable().subscribe(...)进行观察。

Variable附近

BehaviorSubject is a simple wrapper,每次变量值发生变化时都会发送.next个事件。

答案 1 :(得分:0)

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

您提供的第一个代码,您只是创建一个只返回1个值的observable。 Observable.create内的代码每次有人.subscribe()时就会执行一次。

发布更多的意思是在许多订阅者之间共享订阅...最好的情况是,如果您需要从一台服务器收集的特定信息,以便在您的应用中的许多地方使用...您不要我想通过如此多的请求向服务器发送垃圾邮件,因此您只需发出一个请求,发布该请求,观察者将订阅该发布的流。

ReplaySubject(或者BehaviourSubject,但是当你初始化它时你需要知道初始值)更符合你的想法:它既是Observable又是Observer,是其他观察者可以订阅的对象,每当你致电.onNext()时,所有订阅者都会获得一个新值。

Rx不能做魔法,它不知道你何时/如何编辑你的变量。因此,您需要在对象中创建长度为1的ReplaySubject,并将其返回给订阅者。然后在currentIndex更改时跟踪您的代码,在该ReplaySubject上调用onNext方法。