RxSwift中的Subject

什麼是Subject

Rxswift 簡單的分能夠分爲:swift

  • 可觀察序列(Observable
  • 觀察者(Observer
  • 調度者(Scheduler
  • 銷燬者(Dispose

Subject 既能夠作序列,也能夠作觀察者,因爲這個緣由使得 Subject 使用特別方便,在項目中會大量使用。app

Rxswift 中主要有4種 Subjectasync

  • 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 {
    
   ...(省略)
}
複製代碼
  1. 繼承於 Observable<Element>(可被觀察序列),遵循協議:
    • SubjectType —— 既能夠做爲 Observerable 又可做爲 Observer
    • Cancelable —— 能夠被銷燬(繼承於 Disposable
    • ObserverType —— 觀察者
    • SynchronizedUnsubscribeType —— 取消訂閱
  2. 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 {
    
    ...(省略)
}
複製代碼
  1. 繼承於 Observable<Element>(可被觀察序列),遵循協議:3d

    • SubjectType —— 既能夠做爲 Observerable 又可做爲 Observer
    • Cancelable —— 能夠被銷燬(繼承於 Disposable
    • ObserverType —— 觀察者
    • SynchronizedUnsubscribeType —— 取消訂閱
  2. 經過一個初始默認值建立,會存儲上一次信號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 {
    
    ...(省略)
}
複製代碼
  1. 繼承於 Observable<Element>(可被觀察序列),遵循協議:
    • SubjectType —— 既能夠做爲 Observerable 又可做爲 Observer
    • ObserverType —— 觀察者
    • Disposable —— 能夠被銷燬
  2. 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 {
    
    ...(省略)
}
複製代碼
  1. 繼承於 Observable<Element>(可被觀察序列),遵循協議:

    • SubjectType —— 既能夠做爲 Observerable 又可做爲 Observer
    • ObserverType —— 觀察者
    • SynchronizedUnsubscribeType —— 取消訂閱
  2. 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 的封裝
  • PublishSubjectBehaviorSubject 都會被 error 或者 completed 便可以用方法 onError 或者 onCompleted 終止;可是 PublishRelayBehaviorRelay 不會(就沒有 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
複製代碼
相關文章
相關標籤/搜索