RxSwift(二)----Subjects
在RxSwift中有一种东西既能当做observable,又能当做observer,这种就是Subject.在RxSwift中有四种类型的Subject:
-
PublishSubject,初始元素为空,只把新元素发送给其订阅者. -
BehaviorSubject,有初始元素,把最近的元素发送器订阅者. -
ReplaySubject,会缓存一定数量的元素,并将发送给器新订阅者. -
Variable,对BehaviorSubject的封装,将初始值或最近的值发送给其订阅者.
PublishSubject

Snip20181127_14.png
如果只是将新元素发送给订阅者直到订阅者取消订阅或者subject发出.completed或者.error事件为止.
let subject = PublishSubject<String>()
subject.onNext("hello world!")
let subscriptionOne = subject.subscribe { event in
print(event)
}
subject.on(.next("1"))
subject.onNext("2")
let subscriptionTwo = subject.subscribe { event in
print("2) ", event.element ?? event)
}
subject.onNext("3")
subscriptionOne.dispose()
subject.onNext("4")
subject.onCompleted()
subject.onNext("5")
subscriptionTwo.dispose()
let bag = DisposeBag()
subject.subscribe {
print("3) ",$0.element ?? $0)
}
.disposed(by: bag)
打印如下:
next(1)
next(2)
next(3)
2) 3
2) 4
2) completed
3) completed
如果subject发出.completed或者.error,这些都称为完成事件,它将发送这些完成事件给它将来的订阅者,不会发出.next()事件.这样不仅仅可以知道它什么时候终止,还可以知道你可能订阅了一个已经终止了的subject.
BehaviorSubject

Snip20181127_15.png
BehaviorSubject它初始化一个元素,它将最近的元素发送其订阅者.
let subject = BehaviorSubject(value: "hello world!")
let bag = DisposeBag()
// 初始值
subject.subscribe { event in
print("1) ",(event.element ?? event.error) ?? event)
}
.disposed(by: bag)
subject.onError(MyError.anError)
subject.subscribe {
print("2) ",($0.element ?? $0.error) ?? $0)
}
.disposed(by: bag)
打印如下:
1) hello world!
1) anError
2) anError
因为BehaviorSubject它将最近的元素发送给订阅者,所以它必须初始化一个元素,如果你不带初始化元素,你可以用PublishSubject代替.
ReplaySubject

Snip20181127_16.png
ReplaySubject会缓存最近的元素,并将缓存的元素发送给其订阅者.
let subject = ReplaySubject<String>.create(bufferSize: 2)
let bag = DisposeBag()
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject.subscribe { event in
print("1) ",(event.element ?? event.error) ?? event)
}
.disposed(by: bag)
subject.subscribe {
print("2) ",($0.element ?? $0.error) ?? $0)
}
.disposed(by: bag)
subject.onNext("4")
subject.onError(MyError.anError)
subject.subscribe {
print("3) ",($0.element ?? $0.error) ?? $0)
}
.disposed(by: bag)
打印如下:
1) 2
1) 3
2) 2
2) 3
1) 4
2) 4
1) anError
2) anError
3) 3
3) 4
3) anError
如果你缓存的元素太多的话,且是图片对象,这样对内存造成压力,或者是或者的元素是数组,这样也会有很大的缓存压力.
Variables
Variable是对BehaviorSubject的包装,并储存当前的值作为状态,你可以使用value属性获取或者设置值,这样可以不用onNext(_:)方法,
let variable = Variable("hello world!")
let bag = DisposeBag()
variable.value = "hello swift!"
variable.asObservable().subscribe {
print("1) ",($0.element ?? $0.error) ?? $0)
}
.disposed(by: bag)
variable.value = "1"
variable.asObservable().subscribe {
print("2) ",($0.element ?? $0.error) ?? $0)
}
.disposed(by: bag)
variable.value = "2"
打印如下:
1) hello swift!
1) 1
2) 1
1) 2
2) 2
Variable不能添加.error和.completed事件,否则编译器会产生错误.