Subject
Rxswift
簡單的分能夠分爲:swift
Observable
)Observer
)Scheduler
)Dispose
)Subject
既能夠作序列,也能夠作觀察者,因爲這個緣由使得 Subject
使用特別方便,在項目中會大量使用。app
Rxswift
中主要有4種 Subject
:async
PublishSubject
BehaviorSubject
ReplaySubject
AsyncSubject
SubjectType
協議Rxswift
中全部的 Subject
都會遵循 SubjectType
協議。ui
SubjectType
它繼承於 ObservableType
,它能夠做爲一個可觀察的序列。SubjectType
關聯了(associatedtype
)一個觀察者協議(ObserverType
)以及方法 asObserver
,它能夠作爲一個觀察者來使用。/// Represents an object that is both an observable sequence as well as an observer.
public protocol SubjectType : ObservableType {
/// The type of the observer that represents this subject.
///
/// Usually this type is type of subject itself, but it doesn't have to be.
associatedtype SubjectObserverType : ObserverType
/// Returns observer interface for subject.
///
/// - returns: Observer interface for subject.
func asObserver() -> SubjectObserverType
}
複製代碼
PublishSubject
/// Represents an object that is both an observable sequence as well as an observer.
///
/// Each notification is broadcasted to all subscribed observers.
public final class PublishSubject<Element> : Observable<Element> , SubjectType , Cancelable , ObserverType , SynchronizedUnsubscribeType {
...(省略)
}
複製代碼
Observable<Element>
(可被觀察序列),遵循協議:
SubjectType
—— 既能夠做爲 Observerable
又可做爲 Observer
Cancelable
—— 能夠被銷燬(繼承於 Disposable
)ObserverType
—— 觀察者SynchronizedUnsubscribeType
—— 取消訂閱PublishSubject
只能接收在被訂閱以後發送的信號示例:this
let pub = PublishSubject<Int>()
pub.onNext(1)
pub.subscribe(onNext: { (num) in
print("接收到——\(num)")
}).disposed(by: disposeBag)
pub.onNext(2)
pub.onNext(3)
複製代碼
輸出:spa
接收到——2
接收到——3
複製代碼
BehaviorSubject
/// Represents a value that changes over time.
///
/// Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
public final class BehaviorSubject<Element> : Observable<Element> , SubjectType , ObserverType , SynchronizedUnsubscribeType , Cancelable {
...(省略)
}
複製代碼
繼承於 Observable<Element>
(可被觀察序列),遵循協議:3d
SubjectType
—— 既能夠做爲 Observerable
又可做爲 Observer
Cancelable
—— 能夠被銷燬(繼承於 Disposable
)ObserverType
—— 觀察者SynchronizedUnsubscribeType
—— 取消訂閱經過一個初始默認值建立,會存儲上一次信號code
// 初始化默認傳入一個值
public init(value: Element) {
self._element = value
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
}
複製代碼
func _synchronized_on(_ event: Event<E>) -> Observers {
self._lock.lock(); defer { self._lock.unlock() }
if self._stoppedEvent != nil || self._isDisposed {
return Observers()
}
switch event {
case .next(let element):
// 記錄值
self._element = element
case .error, .completed:
self._stoppedEvent = event
}
return self._observers
}
複製代碼
三、訂閱以後首先會接收到最近一次發送的事件(若是最近沒有發送,那麼發送一個初始的事件)cdn
示例:server
let behavior = BehaviorSubject<Int>(value: 1)
behavior.onNext(2)
behavior.subscribe(onNext: { (num) in
print("接收到——\(num)")
}).disposed(by: disposeBag)
behavior.onNext(3)
behavior.onNext(4)
let value = try? behavior.value()
print("value = \(value)")
複製代碼
輸出:
接收到——2
接收到——3
接收到——4
value = Optional(4)
複製代碼
ReplaySubject
/// Represents an object that is both an observable sequence as well as an observer.
///
/// Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
public class ReplaySubject<Element> : Observable<Element> , SubjectType , ObserverType , Disposable {
...(省略)
}
複製代碼
Observable<Element>
(可被觀察序列),遵循協議:
SubjectType
—— 既能夠做爲 Observerable
又可做爲 Observer
ObserverType
—— 觀察者Disposable
—— 能夠被銷燬ReplaySubject
會根據緩衝區調整,每一個信號將廣播給全部已訂閱的觀察者和將來訂閱的觀察者。示例:
let replay = ReplaySubject<Int>.create(bufferSize: 2)
replay.onNext(1)
replay.onNext(2)
replay.onNext(3)
replay.subscribe(onNext: { (num) in
print("第一個訂閱接收到 -- \(num)")
}).disposed(by: disposeBag)
replay.onNext(4)
replay.onNext(5)
replay.subscribe(onNext: { (num) in
print("第二個訂閱接收到 -- \(num)")
}).disposed(by: disposeBag)
複製代碼
輸出:
第一個訂閱接收到 -- 2
第一個訂閱接收到 -- 3
第一個訂閱接收到 -- 4
第一個訂閱接收到 -- 5
第二個訂閱接收到 -- 4
第二個訂閱接收到 -- 5
複製代碼
AsyncSubject
public final class AsyncSubject<Element> : Observable<Element> , SubjectType , ObserverType , SynchronizedUnsubscribeType {
...(省略)
}
複製代碼
繼承於 Observable<Element>
(可被觀察序列),遵循協議:
SubjectType
—— 既能夠做爲 Observerable
又可做爲 Observer
ObserverType
—— 觀察者SynchronizedUnsubscribeType
—— 取消訂閱AsyncSubject
只發送最後一個信號,而且只在完成(onCompleted)以後。
示例1:
let async = AsyncSubject<Int>()
async.onNext(1)
async.onNext(2)
async.subscribe(onNext: { (num) in
print("接受訂閱 = \(num)")
}).disposed(by: disposeBag)
async.onNext(3)
async.onNext(4)
async.onCompleted()
複製代碼
輸出:
接受訂閱 = 4
複製代碼
RxCocoa
中的 PublishRelay
, BehaviorRelay
PublishRelay
是對 PublishSubject
的封裝BehaviorRelay
是對 BehaviorSubject
的封裝PublishSubject
和 BehaviorSubject
都會被 error
或者 completed
便可以用方法 onError
或者 onCompleted
終止;可是 PublishRelay
和 BehaviorRelay
不會(就沒有 onError
或者 onCompleted
方法)/// PublishRelay is a wrapper for `PublishSubject`.
///
/// Unlike `PublishSubject` it can't terminate with error or completed.
public final class PublishRelay<Element>: ObservableType {
public typealias E = Element
private let _subject: PublishSubject<Element>
...(省略)
}
複製代碼
/// BehaviorRelay is a wrapper for `BehaviorSubject`.
///
/// Unlike `BehaviorSubject` it can't terminate with error or completed.
public final class BehaviorRelay<Element>: ObservableType {
public typealias E = Element
private let _subject: BehaviorSubject<Element>
...(省略)
}
複製代碼
PublishRelay
示例:
let publisRelay = PublishRelay<Int>()
publisRelay.accept(1)
publisRelay.subscribe(onNext: { (num) in
print("接收到 -- \(num)")
}).disposed(by: disposeBag)
publisRelay.accept(2)
publisRelay.accept(3)
複製代碼
輸出:
接收到 -- 2
接收到 -- 3
複製代碼
BehaviorRelay
示例:
let behaviorRelay = BehaviorRelay<Int>(value: 1)
behaviorRelay.accept(2)
behaviorRelay.subscribe(onNext: { (num) in
print("接收到 -- \(num)")
}).disposed(by: disposeBag)
behaviorRelay.accept(3)
behaviorRelay.accept(4)
print("value = \(behaviorRelay.value)")
複製代碼
輸出:
接收到 -- 2
接收到 -- 3
接收到 -- 4
value = 4
複製代碼