最近公司在前端架构优化方案时提到了MVP和MVVM两种模式,其实这两种架构从接触移动端开发以来,一直有听到过,但是一直没有深入的去学习理解。借这次App代码重构的机会,我仔细的了解了MVP和MVVM两种架构。其中在接触MVVM时,提到了一种绑定(响应式)的概念,即Model和ViewModel之间双向绑定,View的变动,自动反映在 ViewModel,反之亦然。于是我就想利用业余时间好好学习一下RxSwift,理解这种响应式的方式是如何实现的。

RxSwift的本质

RxSwift官方文档中写到了所有Observable的实例都相当于Swift中的Sequence,并且和Sequence相比它还能异步的接受参数;ObservableType.subscribe(_:)就相当于Swift中的Sequence.makeIterator(),不同的是在RxSwift中不需要手动的调用next()方法,Observable就能自动的将事件发送给Observer。这就是RxSwift的本质,一切都建立在这个基础上。

Observable和Observer

虽然已经很清楚的明白的RxSwift的本质所在,但是不搞清楚ObservableObserver这两个之间的关系,我始终对RxSwift一团污水。其实通过字面意思我们就可以知道Observable是可以被观察的意思,所以它是被观察者,那么Observer就是观察者,在RxSwift中Observer实现了ObserverType,这是一个protocolObserverType约定了一个方法on(_ event: Event<E>)用于封装被订阅者发送的事件回调。事件回调分为nexterrorcompleted三种。同理,Observable也实现了一个协议ObservableTypeObservableType主要约定的方法为subscribe<O: ObserverType>(_ observer: O),subscribe方法开放了自身被订阅的入口,观察者可以通过这个方法订阅被观察对象。

Let‘s Try

这里我省略了RxSwift的一些语法教程,因为本文主要是想要和大家分享我对RxSwift响应式实现的理解。如果有不理解的地方可以直接到github上下载RxSwift-master,里面的Rx.playground是很好的一份RxSwift语法教程。进入正题,以下是一段我用RxSwift写的伪代码,模拟了用户发起网络请求,并将网络请求的结果异步返回给观察者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let observable = Observable.create({ (observer) -> Disposable in
let request = MyRequestAPI.get(url, ( (result, error) -> {
if let err = error {
observer.onError(err)
}
else if let response = result {
observer.onNext(response)
observer.onComplete()
}
})
return AnonymousDisposable {
request.cancel()
}
})

observable.subscribe(onNext: { (response) in
// receive data do some thing
}, onError: { (err) in
// error do some thing
}, onCompleted: {
// complete request do some thing
}, onDisposed: {
// deinit
})

在上面这段代码中,我通过create方法创建了一个observable实例,将MyRequestAPI的返回职能移交给了一个observer对象,当网络请求异常时,我会调用observer.onError(),这意味着,只要监听了这个observable对象,就会接收到错误的消息。事实上在第二段代码中我正是这么做的,通过对observablesubscribe,分别对网络请求的成功返回、异常、结束、释放等状态进行了监听。从而能够在相应的事件到来之际,进行相应的操作。

最初的疑问

现在我们已经对RxSwift的思维有所了解。但心中可能还是有一个疑问,RxSwift是如何实现响应式这种方式的?通过阅读Observable.create的源码,我从中找到了答案。在Rx内部有一个集合Observers,在我们执行监听方法subscribe的时候,以上面代码的onNext为例,此时在其内部会执行_observers.insert(observer.on)这样一段代码,就是将这种状态的监听加入到集合中,待我们调用observer.onNext(response)方法的时候,它会去遍历_observers,如果集合中存在相同的状态类型,则执行对应状态的eventHander闭包。

冰山一角

如果要使用RxSwift实现一个MVVM架构的应用,那上面提到的应用知识只是冰山一角,毕竟RxSwift是一个很庞大的项目,他还有一个名字类似的仓库叫RxCocoa,基本上来说,RxCocoa给所有的 Cocoa 类建立了扩展方法,从而可以让UI视图建立诸如rx.text之类的东西。这样我们就不需要像上面一样手动创建Observable对象,可以少写一点subscribeNext方法,从而在多个不同的视图点中将值和观察值之间建立关联。类似下面的代码这样。

1
2
3
4
5
6
7
8
9
10
11
12
let textField = UITextField()
let delegate = TextFieldDelegate()
textField.delegate = delegate
var rxDidChange = false

_ = textField.rx.text
.skip(1) // Initial value
.subscribe(onNext: { _ in
rxDidChange = true
}, onCompleted: {
completed = true
})

总结

以上是我对RxSwift主要思想的理解,旨在帮助想要入坑RxSwift的朋友更好地入门。毕竟RxSwift是一个比较庞大的体系,通过这次学习还有很多RxSwift的知识和语法没有了解,我也会在这个基础上,继续学习。