抛出问题
开发中最容易犯的错误是忘了每个订阅者都会导致observable
重新执行链式调用。
like this:
1 | func request() -> Observable<String>{ |
三个订阅者会发送三次请求。
解决?
当有多个订阅者去订阅同一个Observable
的时候,我们不希望Observable
每次有新的订阅者都去执行。
RxSwift
提供了很多操作:
share()
、replay()
、replayAll()
、shareReplay()
、publish()
、shareReplayLatesWhileConnected()
, 这么多个,应该选哪一个?
你现在能够说出他们之间的不同吗?
先看下总体的比较,有个大概的了解:
1 表示重播最多bufferSize
个事件
2 表示当订阅者的引用计数大于0时,重播一个事件
共享订阅者
多个订阅者订共享一个订阅者对象
可连接
可连接序列只有调用connect
后才会开始发射值,可以等多个订阅者订阅后再连接。
引用计数
返回的observable
记录了订阅者的数量,当订阅者数量从0变成1,订阅源序列,当订阅者数量从1变成0,取消订阅并重置源序列。
每次订阅者数量从0变成1源序列将会重新被订阅。
重播事件
重播已经发射的事件给订阅者。
replay(bufferSize)
和shareReplay(bufferSize)
最多重播bufferSize
个,而shareReplayLatestWhileConnected
最多一个,当订阅者的引用计数变成0,buffer
会被清空,所以引用计数从0变成1,订阅者不会受到重播事件。
publish
以下例子使用interval
模拟用户输入文本,并进行搜索:
1 | var results:Observable<String>! |
然后去订阅结果:
publish
原来讲到过,只有connect
之后才会发射值。
1 | func publish(){ |
replayAll
重播所有事件:
1 | func replayAll(){ |
replay
replay(bufferSize)
重播指定个数的事件:
1 | func replay(){ |
share
订阅者从1变成0重置序列:
1 | func share(){ |
shareReplay(bufferSize)
在share
的基础重播bufferSize
个值。
1 | func shareReplay(){ |
shareReplayLatestWhileConnected
订阅者从1变成0,缓存区被清空:
1 | func shareReplayLatestWhileConnected(){ |
试试改成shareReplay(1)
,或者不销毁sub
。
总结
可以结合上面的例子,在实际运用中选择合适的接口。
代码见github: