Subject 即是序列也是观察者
- 创建subject类
- 收集观察者回调
- 发送信号
源码解析
// 1:初始化序列
let publishSub = PublishSubject()
// 2:发送响应序列
publishSub.onNext(1)
// 3:订阅序列
publishSub.subscribe { (a) in
print("订阅到了:",a)
}.disposed(by: disposeBag)
// 再次发送响应
publishSub.onNext(2)
publishSub.onNext(3)
订阅到了: next(2)
订阅到了: next(3)
步骤1
- PublishSubject类继承Observable类,实现了SubjectType、Cancelable、ObserverType、SynchronizedUnsubscribeType协议。
public final class PublishSubject
: Observable
, SubjectType
, Cancelable
, ObserverType
, SynchronizedUnsubscribeType {
}
步骤2 外界调用subscribe(_ on)
- 来到ObservableType协议的subscribe(_ on)方法
public func subscribe(_ on: @escaping (Event) -> Void)
-> Disposable {
let observer = AnonymousObserver { e in
on(e)
}
return self.asObservable().subscribe(observer)
}
步骤3 来到PublishSubject重写的subscribe
-
self._observers.insert(observer.on)
收集观察者回调
public override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element {
self._lock.lock()
let subscription = self._synchronized_subscribe(observer)
self._lock.unlock()
return subscription
}
func _synchronized_subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element {
if let stoppedEvent = self._stoppedEvent {
observer.on(stoppedEvent)
return Disposables.create()
}
if self._isDisposed {
observer.on(.error(RxError.disposed(object: self)))
return Disposables.create()
}
let key = self._observers.insert(observer.on)
return SubscriptionDisposable(owner: self, key: key)
}
struct SubscriptionDisposable : Disposable {
private let _key: T.DisposeKey
private weak var _owner: T?
init(owner: T, key: T.DisposeKey) {
self._owner = owner
self._key = key
}
func dispose() {
self._owner?.synchronizedUnsubscribe(self._key)
}
}
步骤4 外界调用onNext
- 来到ObserverType 扩展的 onNext
- 执行self.on(.next(element)) 去到PublishSubject 的on方法
extension ObserverType {
/// Convenience method equivalent to `on(.next(element: Element))`
///
/// - parameter element: Next element to send to observer(s)
public func onNext(_ element: Element) {
self.on(.next(element))
}
/// Convenience method equivalent to `on(.completed)`
public func onCompleted() {
self.on(.completed)
}
/// Convenience method equivalent to `on(.error(Swift.Error))`
/// - parameter error: Swift.Error to send to observer(s)
public func onError(_ error: Swift.Error) {
self.on(.error(error))
}
}
步骤5 PublishSubject的on方法
- dispatch() 方法执行
public func on(_ event: Event) {
#if DEBUG
self._synchronizationTracker.register(synchronizationErrorMessage: .default)
defer { self._synchronizationTracker.unregister() }
#endif
dispatch(self._synchronized_on(event), event)
}
func _synchronized_on(_ event: Event) -> Observers {
self._lock.lock(); defer { self._lock.unlock() }
switch event {
case .next:
if self._isDisposed || self._stopped {
return Observers()
}
return self._observers
case .completed, .error:
if self._stoppedEvent == nil {
self._stoppedEvent = event
self._stopped = true
let observers = self._observers
self._observers.removeAll()
return observers
}
return Observers()
}
}
步骤6 dispatch
- bag._value0?(event),执行观察者的on方法
@inline(__always)
func dispatch(_ bag: Bag<(Event) -> Void>, _ event: Event) {
bag._value0?(event)
if bag._onlyFastPath {
return
}
let pairs = bag._pairs
for i in 0 ..< pairs.count {
pairs[i].value(event)
}
if let dictionary = bag._dictionary {
for element in dictionary.values {
element(event)
}
}
}
ObserverBase on
class ObserverBase : Disposable, ObserverType {
private let _isStopped = AtomicInt(0)
func on(_ event: Event) {
switch event {
case .next:
if load(self._isStopped) == 0 {
self.onCore(event)
}
case .error, .completed:
if fetchOr(self._isStopped, 1) == 0 {
self.onCore(event)
}
}
}
func onCore(_ event: Event) {
rxAbstractMethod()
}
func dispose() {
fetchOr(self._isStopped, 1)
}
}
AnonymousObserver onCore,执行闭包
final class AnonymousObserver: ObserverBase {
typealias EventHandler = (Event) -> Void
private let _eventHandler : EventHandler
init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
self._eventHandler = eventHandler
}
override func onCore(_ event: Event) {
return self._eventHandler(event)
}
#if TRACE_RESOURCES
deinit {
_ = Resources.decrementTotal()
}
#endif
}