要对RX的核心逻辑有所了解,首先应该对Swift的闭包能够很好的理解。
在Swift的AIP中有如下的一个描述:
闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的匿名函数(Lambdas)比较相似。
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。被称为包裹常量和变量。 Swift 会为你管理在捕获过程中涉及到的所有内存操作。
Swift的AIP的在线查看地址:https://www.runoob.com/manual/gitbook/swift5/source/_book/chapter2/07_Closures.html
本文首先是以block的方式去理解RX的逻辑的实现的。
RXSwift的核心逻辑分为三步:
- 创建可观察序列
let observa = Observable<Any>.create { (obserber) -> Disposable in
print("create的内部打印--1")
//obserber.onNext("onNext--1")
//obserber.onNext("onNext--2")
//obserber.onCompleted()
print("create的内部打印--2")
return Disposables.create()
}
这里附上RX家族对create函数的解释:
http://reactivex.io/documentation/operators/create.html
大概意思就是(百度翻译的0.0):
您可以使用Create 运算符从头开始创建Observable 。您将此运算符传递给接受观察者作为其参数的函数。通过调用观察者的-因此,它表现为一个可观察写这个功能onNext, onError和onCompleted适当的方法。
格式良好的有限Observable必须尝试将观察者的onCompleted 方法恰好调用一次或者只调用其onError方法一次,并且此后不得尝试调用任何观察者的其他方法。
我的理解就是:
create后面其实是一个闭包,接收一个(obserber) 后返回Disposable,
其实也就是一个block(可以这样去理解),如果我们就这样直接运行代码,是不会得到任何打印的,因为没有一个self.block(obserber)的调用。所以就涉及到RX的第二步:
2.订阅
let _ = observa.subscribe(onNext: { (text) in
print("订阅到:\(text)")
}, onError: { (error) in
print("error: \(error)")
}, onCompleted: {
print("完成")
}) {
print("销毁")
}
通过observa.subscribe(....),会让程序去执行create后面的闭包,所以我们会第一时间得到一个 "create的内部打印"
而在observa.subscribe内部,onNext,onError,onCompleted,分别都是对应了一个闭包(一个block的实现),而这个block代码块的调用是在
{ (obserber) -> Disposable in
//在这里去对observa.subscribe里面的block实现进行了一个调用
}
所以RX的核心步骤第三步是在:
let observa = Observable<Any>.create { (obserber) -> Disposable in
print("create的内部打印")
// 第三步:发送信号
obserber.onNext("onNext--1")
obserber.onNext("onNext--2")
obserber.onCompleted()
print("create的内部打印--2")
return Disposables.create()
}
以上代码运行会打印如下:
屏幕快照 2019-07-21 17.02.09.png
如果用在一个rx的实际例子中:比如btn的点击
swift的写法是:
self.button.addTarget(self, action: #selector(self.buttonClick(btnclick:)), for: .touchUpInside)
RXSwift就是在这个addTarget方法基础上添加了一个 RX内部类: self.button.addTarget(RX内部类),
然后通过 RX内部类 去实现了 #selector( ...... ) , 而selector里面实现是通过 selector( obserber.onNext() ) ,obserber.onNext() 调用的就是一个btn 的 selector事件具体实现的代码块。
以下我们通过对源码的查看验证步骤是否正确:
1.查看create方法
屏幕快照 2019-07-21 17.38.43.png
发现方法返回了一个 内部类(AnonymousObservable)的初始化AnonymousObservable(subscribe),
2.查看这个内部类
1.jpeg
可以看到内部类(AnonymousObservable)调用了init方法初始化保存了subscribe,也就是create方法后面的闭包。
3.查看observa.subscribe
2.jpeg
let observer 这个常量指向了一个 AnonymousObserver<E>类,后面还一个尾随闭包,通过AnonymousObserver的实现可以看到
对 subscribe创建的 onNext,onError,onCompleted,onDisposed 四个闭包进行了保存。
111563704558_.pic.jpg 其中实现图片 (名称 WechatIMG2)中2-->3步骤的是如下方法 WechatIMG18.jpeg
WechatIMG18.jpeg
通过 Disposables.create 方法去调用了self.asObservable().subscribe(observer),其中对onNext,onError,onCompleted,onDisposed的判断则在subscribe(observer)方法中。
最后,这里在做一点补充,点击observa.subscribe
去查看内部实现时,我打了两个断点,如图:
我在
56
行,和79
行下了断点,运行代码,就会发现,首先是56号断点执行,然后程序并不是直接到79号断点,而是会多出进入
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
一直到我们创建的observa.subscribe
执行完毕,才会走79号断点return。
原因是:这个地方断的是 return的函数,这个return的函数是会先执行 参数(self.asObservable().subscribe(observer),disposable
) 然后给我们的参数回调值
.也就是说,我们的函数内的参数,如果是一个函数,那么会先执行参数函数
。
网友评论