简体   繁体   English

RxSwift:如何使用shareReplay懒惰地获得订阅

[英]RxSwift: How to use shareReplay to lazily get subscription

So I want to be able to lazily subscribe to shared data without it persisting when nobody is subscribed. 因此,我希望能够懒惰地订阅共享数据,而不会在没有人订阅时保持共享数据。 Then if someone subscribes again, a new observable will be created. 然后,如果有人再次订阅,将创建一个新的observable。 I would use a Variable, but I don't want it to persist if no one is subscribed (because if I were using arrays or something larger than an int I don't want to keep them in memory). 我会使用一个变量,但如果没有人订阅我不希望它持续存在(因为如果我使用数组或大于int的东西我不想将它们保留在内存中)。 My current implementation works, except when resubscribing it still gets the last value, which means the value is still persisted. 我当前的实现工作,除了重新订阅它仍然获得最后一个值,这意味着该值仍然是持久的。 I'm thinking of setting the observable to nil, but I don't know where to do that. 我正在考虑将observable设置为nil,但我不知道该怎么做。 Can anyone help me complete this? 任何人都可以帮我完成这个吗? The code below shows it mostly working, but it looks like the data is sticking around when no one is subscribed. 下面的代码显示它主要起作用,但看起来数据在没有人订阅的情况下仍然存在。

    var switchTwoDisposable: Disposable? = nil
​    
    @IBAction func switchOneChanged(sender: UISwitch) {
        if sender.on {
            self.switchOneDisposable = currentNumber().subscribeNext { (value) in
            log.debug("Switch 1: \(value)")
        }
      } else {
        switchOneDisposable?.dispose()
      }
    }
    ​
    @IBAction func switchTwoChanged(sender: UISwitch) {
      if sender.on {
        self.switchTwoDisposable = currentNumber().subscribeNext { (value) in
          log.debug("Switch 2: \(value)")
        }
      } else {
        switchTwoDisposable?.dispose()
      }
    }
    ​
    var numberObservable: Observable<Int>? = nil
    ​
    func currentNumber() -> Observable<Int> {
      if let number = numberObservable {
        return number
      }
      self.numberObservable = Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).shareReplay(1)
      return self.numberObservable!
    }
    ​
    ​
    // Switch 1 turned on
    // logs "Switch 1: 0"
    // logs "Switch 1: 1"
    // Switch 2 turned on
    // immediately logs "Switch 2: 1"
    // logs "Switch 1: 2"
    // logs "Switch 2: 2"
    // Switch 1 turned off
    // logs "Switch 2: 3"
    // Switch 2 turned off
    // nothing happens here until we take action again
    // Switch 1 turned on
    // logs "Switch 1: 3"
    // logs "Switch 1: 0"

I finally found the convenient method that does exactly what I need. 我终于找到了方便的方法,完全符合我的需要。 shareReplayLatestWhileConnected() on an observable will replay the latest value to the 2nd, 3rd, 4th, etc. subscribers, but when everyone unsubscribes, then the last value is not retained. shareReplayLatestWhileConnected()上的shareReplayLatestWhileConnected()会将最新值重播给第2,第3,第4等订阅者,但是当每个人都取消订阅时,则不会保留最后一个值。

From the example above replace this line: 从上面的例子中替换这一行:

self.numberObservable = Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).shareReplay(1)

...with this line: ......用这一行:

self.numberObservable = Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).shareReplayLatestWhileConnected()

Update 更新

In my case, I specifically want to get a value from disk (eg Core data or NSUserDefaults) and then if someone updates that value, they can post to a notification that I'll observe with rx_notification . 在我的情况下,我特别想从磁盘获取一个值(例如Core数据或NSUserDefaults),然后如果有人更新了该值,他们可以发布我将用rx_notification观察到的通知。 Therefore, in order for this lazy loading to truly work, I would also want an initial value. 因此,为了使这个延迟加载真正起作用,我还想要一个初始值。 Therefore it would be helpful to use startWith in this case, where the value given to startWith is the current value on disk. 因此,在这种情况下使用startWith会很有帮助,其中给startWith的值是磁盘上的当前值。 So the code would be analogous to: 所以代码类似于:

Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).startWith(100).shareReplayLatestWhileConnected()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM