Make writing a habit together! This is the 11th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

This paper mainly introduces the mapping operation in RxSwift map principle analysis, about the MAP in SWIFT can see the previous article swift array swift in the use of higher-order functions. Essentially, you get a new structure by facilitating the TrasForm transformation.

1. map

So let’s see first we use RxSwift to convert the elements in our array to a string

let disposeBag = DisposeBag()
let ob = Observable.from([1.2.3])

                ob.map{"\ [$0)"}

                .subscribe(onNext: {print($0.description)})

                    .disposed(by:disposeBag )// prints the result strings 1,2,3
Copy the code

Let’s take a look at the implementation. Click on the map

It is an extension of the observable sequence protocol that defines a map method. So all of our observable sequences have the map method, which returns an observable sequence. Map(source: self.asObservable(), transform: transform)

The Map class initializes the source sequence and saves our Map’s closure transform. In this case, the Map class inherits from Producer and therefore has the ability to subscribe. The process here is the same as the previous analysis. When subscribing, the user enters the subscribe method of Producer

The first time you enter a thread that needs to be boundScheduling environmentLater articles on scheduling will be analyzed. It’s going to go through the sequence run method, ourMap.runThe observer that is threaded in here is the anonymous observer that we created when we subscribedAnonymousObserverThe core logic has been analyzed in previous articles.

Continue to see

Normally we do that heresink.runBut here again the swim takes place through the source observable sequencesubscribeSubscription. This will follow the subscription process we analyzed earlier

Our source sequence is via the convenient methodfromCreated, so the source observable sequence isObservableSequencetype

So let’s look at ObservableSequence’s run method

With the tube sink associated with the observer and sequence, the Observer saves the MapSink of the Transform closure for us and looks at the tube’s run method.

We can see that there is an iterator inside, where parent is the source sequence when we start, and we continueforwardOn

The observer here is mapsink so let’s look at mapsink’s on method

We’ll be kept heretransformThe closure is called, and then theforwardOnEvents.

Sink into the parent classforwardOnMethod, at which point in the next event our element starts fromInt is converted to string. At this point our observer is the anonymous observer that we created when we subscribed

sequentialonCoremethods

Finally, the anonymous observer’s event closure is called

2. flatMap

The higher-order function of flatMap in Swift is

You can seeflatMapI’m flattening an array of arrays, which is equal toA two-dimensional array is converted to a one-dimensional array. What about in RxSwift?

The flatMap operator will sourceObservableApply a conversion method to each of the signals and convert them toObservables. And then take thoseObservablesAnd then send it out.

/ / structure
struct Player {

    let score: BehaviorRelay<Int>

    

    init(score:Int) {

        

        self.score = BehaviorRelay(value: score)

    }

    

}

        let playerA = Player.init(score: 20)

        let playerB = Player.init(score: 30)

        let player = BehaviorRelay(value: playerA)

        

        player.asObservable()

            .flatMap { (player:Player) ->Observable<Int> in

                player.score.asObservable()

            }.subscribe { (num) in

                print(num)

            } onError: { (error) in

                print(error)

            } onCompleted: {

                print("completed")

            } onDisposed: {

                print("disposed")

            }.disposed(by: disposBag)

        

        playerA.score.accept(40)

        playerB.score.accept(50)

        player.accept(playerB)

        playerB.score.accept(60)
        playerA.score.accept(70)


Copy the code

Let’s look at the core logic

Save our source sequence and usflatMapThe conversionclosureThis closure returns an observable sequence. Again, when we subscribe, we go into the run method, because ourFlatMapSinkInheritance inMergeSinkSo sink.run will entermergeSinkIn the run method of

The subscription from our source sequence was passed in to our FlatMapSink, which followed the subscription method of our Soucre sequence. At this point, our sequence BehaviorRelay was called

Here you subscribe with the type of your own source sequence. Our FlatMapSink has no on method, so we go to its parent class to find it.

This is the core

Here the concrete implementation of calling the subclass’s performMap, or FlatMapSink, returns a new observable sequence

Make internal subscriptions

The new sequence then sends the event

Make a callback.

3. Summary

For the mapping operation Map, we will introduce these two types here, and the specific situation is still to break point analysis.

  • map

When element of our observable sequence is an array, we store a closure through map, and when sending signals, we process our sending element element through a layer of transform closure callbacks, followed by eventHanlde callbacks to subscribers.

  • Flatmap

In fact, we are similar to FlatMap from the bottom. Instead of transforming elements, we transform sequence sources. Our sequence is like an intermediate layer.