Driver
Case introduced
Request a network and bind to the UI
Using Observerable
let result0 = inputTF.rx.text.skip(1) .flatMap { [weak self](input) -> Observable<Any> in return (self? .dealwithData(inputText:input ?? ""))! .observeon (mainscheduler.instance).catchErrorJustreturn (" error event detected ")}.share(replay: 1, scope: .whileConnected) // share(replay: 1, scope: Result0. Subscribe (onNext: whileConnected) Result0: \(element) in print(" Result0: \(element)")}). Subscribe (by: disposeBag) result0. Subscribe (onNext: {(element) in print(" Result0: \(element) - \(thread.current)")}). Disposed (by: disposeBag)Copy the code
The Driver
Titlt - non-error let result = inputtf.rx.text.orempty.asdriver ().flatmap {return Self. dealwithData(inputText: $0).asDriver(onErrorJustReturn: "Error event detected ")} result.map {" Length: \(($0 as! String).count)"} .drive(self.textLabel.rx.text) .disposed(by: disposeBag) result.map { "\($0 as! String)"} .drive(self.btn.rx.title()) .disposed(by: disposeBag)Copy the code
Observable<Any>{print(" request network \(thread.current)") // data return Observable<Any>.create({ (ob) -> Disposable in if inputText == "1234" { ob.onError(NSError.init(domain: "Com.pxwx.www ", code: 10086, userInfo: nil))} dispatchqueue.global ().async {print(" Send before look: \(thread.current)") ob.onnext (" Already entered :\(inputText)") ob.oncompleted ()} return Disposables. Create ()})}Copy the code
What is an old driver
Drivers are arguably the most complex traits, and their goal is to provide an easy way to write responsive code at the UI layer. 2. We can use it if our sequence column meets the following characteristics:
- No error events are generated
- Must be listening on the MainScheduler
- Shared state changes (shareReplayLatestWhileConnected)
Why use Driver?
The most common use of a Driver is when a sequence is required to drive an application, such as:
- The UI is driven through the CoreData model
- Use one UI element value (binding) to drive another UI element value
2. As with normal operating system drivers, the application will stop responding to user input if a sequential column error occurs. 3. It is also extremely important to observe these elements on the main thread, because UI elements and application logic are generally not thread-safe. 4. In addition, use the observable sequence column that builds the Driver, which shares state changes.
Basic Source code parsing
A Driver is simply an alias for a sequence that is easy to remember.
public typealias Driver<Element> = SharedSequence<DriverSharingStrategy, Element>
Copy the code
OK! We see source.share(replay: 1, scope:.whileconnected) as a Driver that encapsulates a sequence.
Subject
Let’s look at a very special type — Subject. Why is it special? The reason is simple: Subject can act as both sequence and observer, so it is widely used in practical development because of this characteristic. Let’s interpret this particular Subject.
The basic principle of
First, let’s look at how SubjectType works
Public Protocol SubjectType: ObservableType {// AssociatedType SubjectObserverType subjecTOBType: ObserverType func asObserver() -> SubjectObserverType }Copy the code
SubjectType
The first is inheritanceObservableType
, with sequence characteristics- Associated with the observer type, has the ability of that type
- Let’s get a feel for ‘subject’ through a concrete type
- Obviously being able to subscribe to signals (the basic ability of sequences)
- The ability to send a response, again, is the observer’s ability
- View the underlying source code analysis
Subscription response process
self._observers.insert(observer.on):
By adding all subscription events to a collection, it is obvious that they are all executed at once in the right place- It also returns the destroyer of this subscription to facilitate cleanup:
synchronizedUnsubscribe
->self._observers.removeKey(disposeKey)
- Convenience by
key
Get a responsebag
To perform collection removal - Because there is no corresponding holding relationship, automatic release destruction is achieved
Signal sending process
- This place might look a little messy and gross to you, but you can see it from the heart
- This is basically called
dispatch
The function passes two arguments:self._synchronized_on(event)
andevent
- To view
dispatch
Function source code
bag._value0? (event)
The callback to the event is performed first- judge
bag._onlyFastPath
By default, the fast channel will be opened! - If you want to enable the slow channel, add it from the previous step
bag
Matches are made one by one inside the packagepairs[i].value(event)
, and then gets back the closure call of the enclosing closure:element(event)
- Here if
self._isDisposed || self._stopped
True returns an empty set, and there is no sequence of responses - in
.completed, .error
Will change the stateself._stopped = true
That is, the sequence cannot respond again after completion or error - in
.completed, .error
It also removes content added to the collection
In fact, if you understand the flow of the previous sequence, this
subject
I’m not talking about it anymore. It’s justsubject
The subscription and response processes are implemented internally, so there is no need to introduce themsink
A variety of Subject
PublishSubject
It can be initialized without initialization (that is, null), and it will only send elements to the subscriber that were received after the subscription.
// PublishSubject // 1: initializes the sequence let publishSub = PublishSubject<Int>() // Initializes the sequence of PublishSubject with type Int // 2: sends the response sequence Publishsub. onNext(1) // 3: Subscribe sequence publishsub. subscribe {print(" Subscribe to :",$0)}. Disposed (by: Disposbag) // Send response publishsub.onNext (2) publishsub.onNext (3) /* Subscribed: next(2) subscribed: next(3) */Copy the code
Signal: 1.
Can not be subscribed, only the response after the subscription is accepted
BehaviorSubject
This is created with a default initialization value. When a subscriber subscrires to a BehaviorSubject, it receives a BehaviorSubject Event emitted after the subscription, or a default value emitted if no data has been received. The new event is then received as normal as the PublishSubject.
Slightly different from the PublishSubject BehaviorSubject, this BehaviorSubject has a store function: it stores the last signal
Print ("**********BehaviorSubject**********") // BehaviorSubject // 1: Create a sequence let behaviorSub = behaviorSubject.init (value: 1) // 2: Signal behaviorSub.onNext(2) behaviorSub.onNext(3) // 3: Subscribe sequence behaviorSub.subscribe{print(" Subscribe :",$0)} .disposed(by: OnNext (4) behaviorSub.onNext(5) // Subscribe again behaviorSub.subscribe{print(" Subscribed :",$0)} Disposed (by: disposbag) / * * * * * * * * * * * BehaviorSubject * * * * * * * * * * subscribe to: next (3) subscribe to: next (4) subscribe to: next (5) subscribe to: next(5) */Copy the code
- When no signal is available, it is sent by default
Signal: 100
- Only one signal can be stored:
Signal 2
Will beSignal 3
cover - The ability to store signals before subscribing to them
- Class with a property that holds a signal
- Event response: The new event overwrites the original event
- Other processes and
publish
The same
ReplaySubject
ReplaySubject sends all events of the source Observable whenever the Observer subscribes.
Print (" * * * * * * * * * * ReplaySubject * * * * * * * * * * ") / / ReplaySubject / / 1: create sequence let replaySub = ReplaySubject<Int>.create(bufferSize: 2) // Let replaySub = ReplaySubject<Int>. CreateUnbounded () // 2: send signals replaysub.onNext (1) replaysub.onnext (2) Replaysub. onNext(3) Replaysub. onNext(4) // 3: Subscribe replaysub. subscribe{print(" Subscribe to :",$0)}. Disposbag) // Replaysub.onNext (7) replaysub.onnext (8) replaysub.onnext (9) /* **********ReplaySubject********** Subscribed: next(3) subscribed: next(4) subscribed: next(7) subscribed: next(8) subscribed: next(9) */Copy the code
- a
bufferSize
Space, store as many responses as you want - call
addValueToBuffer
The function adds the sent element toqueue
In the. - call
trim
The function to deletequeue
In more thanbufferSize
The superfluous element of. - Other procedures remain the same
- The source code is relative to
BehaviorSubject
The storage property of the
AsyncSubject
The AsyncSubject sends only the last event sent by the source Observable, and only after the source Observable has completed. (If the source Observable does not send any value, the AsyncSubject does not send any value either.)
Print (" * * * * * * * * * * AsyncSubject * * * * * * * * * * ") / / AsyncSubject / / 1: create sequence let asynSub = AsyncSubject < Int >. The init () / / 2: send a signal Asynsub. onNext(1) Asynsub. onNext(2) // 3: Subscribe asynsub. subscribe{print(" Subscribe to :",$0)}. OnNext (3) asynsub. onNext(4) asynsub. onError(nseror.init (domain: "PXWX ", code: 10086, the userInfo: nil)) asynSub. OnCompleted () / * * * * * * * * * * * AsyncSubject * * * * * * * * * * subscribe to: error(Error Domain=pxwx Code=10086 "(null)") */Copy the code
Variable
Variable deprecated, here is the code for you to encounter the old version! Because of the flexibility of this Variable, it is widely used in development.
print("**********Variable**********")
// Variable : 5.0已经废弃(BehaviorSubject 替换) - 这里板书 大家可以了解一下
// 1:创建序列
let variableSub = Variable.init(1)
// 2:发送信号
variableSub.value = 100
variableSub.value = 10
// 3:订阅信号
variableSub.asObservable().subscribe{ print("订阅到了:",$0)}
.disposed(by: disposbag)
// 再次发送
variableSub.value = 1000
/*
**********Variable**********
订阅到了: next(10)
订阅到了: next(1000)
*/
Copy the code
BehaviorRelay
- Replace the original
Variable
- You can store a signal
- Anytime subscribe response
- Note when sending responses:
behaviorR.accept(20)
print("**********BehaviorRelay**********") let behaviorRelay = BehaviorRelay(value: 61) behaviorRelay. Subscribe (onNext: {(num) in print(" Subscribe to :\(num)")}). Disposed (by: Disposbag) behaviorRelay. Accept (1000) /* ********** behaviorRelay ********** Subscribed :100 Subscribed :1000 Subscribed: completed */Copy the code
Sharing:Swift Information Download
Since the | address