Make writing a habit together! This is the third day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details. In the previous article, we analyzed the core logic of RxSwift. This article mainly introduces the inheritance and protocol of observer and sequence in RxSwift.

1.Observable sequence inheritance chain

We analyzed sequence creation, subscription, and sending signals earlier.

/ / 1. To create

        let ob = Observable<Any>.create{ (obserber) -> Disposable in

            

            //3. Send signals

            obserber.onNext("hello")

            obserber.onError(NSError.init(domain: "NetWorkError".code: 400.userInfo: nil))

            //obserber.onCompleted()

            return Disposables.create()

            

        }

        / / 2. Subscription

        

        ob.subscribe(onNext: { (value) in

            

            print(value)

            

        }, onError:{ (error) in

            

            print(error)

            

        } , onCompleted: {

            

            print("Subscription completed")},onDisposed: {

            print("Subscription Destruction")

        }).disposed(by: disposeBag)
Copy the code

Basically, the core logic is: create a sequence, subscribe to a sequence, destroy a sequence. The central idea is that everything can be sequenced

Observable Observable sequence, AnonymousObservable is created in Observable

. Create. This sequence does two things: one is to save the _subscribeHandler closure initially created. Override the run method

  • Let’s keep lookingProducer

It is a producer, primarily through subscriptions to sequences, associated observers, destruction, and thread management. As a parent, these capabilities are given to subclasses, but the implementation is up to the subclasses themselves.

The run method, for example, defines an abstract method whose implementation is implemented by subclasses.

  • We seeProducerContinue toObservable

As you can see, as the base class of all sequences, it provides the simplest methods to manage reference counts through init and deinit, similar to how ARC manages reference counts, and exposes the subscribe method and asObservable() method that implement the protocol. The asObservable() method converts subclasses to the type Observable

, so we can subscribe. Because subclasses are constantly defined, the current class is no longer very simple. By constantly grading granularity we can clarify the responsibilities and permissions of each class, making the code more robust. Their relationship is similar to: subclass -> parent -> base class.

  • ObservableType

A sequence can produce zero or more elements, so zero or more ‘Next’ events can be sent to the ‘observer’ once the ‘Error’ or ‘Completed’ event is sent, the sequence terminates and no other elements can be produced. Events may be sent from different threads, but you cannot send both events to the observer at the same time. We define a Subscribe event and extend the default implementation of asObservable().

  • ObservableConvertibleType

ObservableType followed ObservableConvertibleType agreement at the same time, mainly provides asObservable () method.

For sequences, we can get their relationship:

2. The succession chain of the subscriber Observer

We previously analyzed that the AnonymousObserver AnonymousObserver was created when sequential subscriptions were made. Let’s look at the AnonymousObserver

You can see that it will hold the initialization constructor will hold the eventHandler, which is the callback closure that we defined outside. Rewrite the onCore method to implement the eventHandler(event) callback, and init and deinit to handle reference counting.

  • ObserverBase

For the base observer, the onCore method is mainly provided for subclasses to implement concrete closure callbacks, while the own ON method calls its own abstract interface onCore

  • agreement

The main definition of the on method, while defining the implementation of onNext, onCompleted, onError through on.

Disposable mainly defines the dispise () method

  • AnyObserver

For our AnonymousObserver AnonymousObserver we usually don’t want to tell the outside world, so we convert to AnyObserver to forward the action to any underlying observer with the same “Element” type, hiding the details of the underlying observer type.

Save our on method in AnonymousObserver, also known as the eventHandler closure, and call back with the ON method

We can look at the diagram

3. Sink’s inheritance chain

For Sink, we can understand it as a manager, similar to manager. Obserbale holds the observer observer and Obserbale sequence, sends messages through observer.on, and executes a callback upon receiving the message. Let’s look at the sequence created in AnonymousObservablerun

  • AnonymousObservableSink

You can see that in the initialization, the AnonymousObserver is saved, and the run method is used to save the sequence AnonymousObservable, which is the parent.

Event callbacks are made through the on method of the protocol ObserverType

  • Sink

For the forwarding method that Sink defines mainly on, the forwardOn invokes the on method that follows the protocol ObserverType.

4. To summarize

For RxSwift, we mainly create, subscribe, and destroy sequences (not covered for now, but more on that later). By combing observable sequence and observer, we can find its inheritance chain and protocol that it follows, we can find the charm of RxSwift framework design, clear responsibilities of class functions and protocol-oriented programming. Sink is a sequence of managers and observers, which is responsive.