RxSwift高阶函数之map映射

468 阅读2分钟

map 操作符将源 Observable 的每个元素应用你提供的转换方法,然后返回含有转换结果的 Observable —— 新的可观察序列。

示例:

let ob = Observable.of(1, 2, 3, 4)
      
ob.map { (num) -> Int in
    return num + 2
}
.subscribe(onNext: { (num) in
    print("num: \(num)")
})
.disposed(by: disposeBag)
打印结果:
num: 3
num: 4
num: 5
num: 6

map源码分析

点击 map 函数进入源码来到这里。

根据经验,我们应该去查找Map文件。如果没有这个经验或者不知道怎么查找的小伙伴,请移步我之前的博客。^_^
Map文件中找到 map 函数。其中调用了

self.asObservable().composeMap(transform)

在之前的文章中已经分析过了,asObservable() 的作用是将返回 self 并转换为 Observable 对象。因此,我们在查找 composeMap 函数的源码时,应该找

Observable 中的 composeMap函数。我们继续查看源码。

这里调用又了一个函数 _map,继续查看。
就会发现,最终是初始化了一个继承自 ProducerMap 对象的实例。并在初始化时保存了,源序列 source 和 转换方法 transform

上面的分析就是调用 map 函数的过程。而且知道 Map 对象是继承自 Producer 对象的。 看过RxSwift核心逻辑分析的小伙伴应该知道可观察序列在 subscribe 时,最后会调用子类的 run 函数。那我们来分析 Map 对象的 run 函数。

    override func run<O: ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == ResultType {
        let sink = MapSink(transform: self._transform, observer: observer, cancel: cancel)
        let subscription = self._source.subscribe(sink)
        return (sink: sink, subscription: subscription)
    }

run 函数中,初始化了 MapSink 对象,并在其中保存了转换方法和观察者。具体分析可类比RxSwift核心逻辑分析中的 AnonymousObservableSink

之后,执行了 self._source.subscribe(sink) 这是对原序列进行了订阅!!!因为,发送原始信号的肯定是源序列,没有其他了。

因此最终,会来到 sinkon 函数。所以我们重点分析 MapSinkon 函数。

当信号来到这里之后,会执行 let mappedElement = try self._transform(element)。对信号使用转换方法进行转换包装,变成一个新的信号,再返回给观察者,完成转换过程。

以上则是 map 函数的转换过程。若有不足之处,还请小伙伴们评论指正。