RxSwift到底解决问题什么问题

之前学了下RAC,在RAC当中的话其实基本都是block,它的中心思想其实包含了KVO和迭代器模式的思想下一步需要做什么还有就是函数式编程。

在RxSwift中有几个概念比较重要的就是Observer也就是观察者,而Observerable是可被观察者,这个是个事件源,我们的观察者需要去订阅这个事件源

才会去收到消息的通知。在RxSwift中会把每个事件源都去看作是一个序列(sequence)。

下面我们会去进行调用最多的就是pleted:


其中上面调用的是on:Event订阅所有的内容了就是说不管发生了错误也好还是完成了也好我都会去监听,去做处理


接下来我们还可以自己去创建一个自定义序列,这里把可被观察者给创建出来了,然后这个函数接收观察者作为其的参数

再简单的介绍下Subject,Subject即可以是Observable也可以是一个Observer,也就是说它是一个既可以去发送事件也可以去监听事件。

PublishSubject:订阅PublishSubject的时候,只能接收到订阅它之后发生的事件,前面发送的事件是不会接受的

//创建序列中一个事件,这个事件的内容是Hello

ReplaySubject:订阅ReplaySubject的时候,可以接收到订阅它之后的事件,也可以接受订阅它之前发出的事件,接受几个事件取决与bufferSize的大小,下面就是只去接收前面两个事件

BehaviorSubject:订阅了BehaviorSubject,默认情况下订阅者只能接受前面的最新的一条消息,而后面的都可以收到,这里的BehaviorSubject其实也就是为了防止第一个订阅者没有一个前一个信号可以接收而设立的


Variable的使用,其实可以看出和BehaviorSubject一样都是只接收了上面的最新的一个信号,而后面的都是全部接收的,以及在通过asObservable()创建的序列释放的时候会去发送completed信号,因为当我们把variable设为全局属性的时候是没有去打印complete的

一般我们在开发的时候都会去创建一个全局的DisposeBag,就比如说我们可以把它引用为我们的属性,Disposebags 的作用跟ARC类似。当一个 Disposebags 被释放时,它会对内部每一个可以被清理的元素调用 dispose。DisposeBag 没有 dispose 方法,所以我们肯定不能去手动的调用。如果我们需要立即的清理资源,可以创建一个新的DisposeBag去替换掉我们之前强引用的那个Disposebags。用到这个主要想在事件完成之后去取消订阅,减少内存的使用和性能上面的消耗

一行代码可以绑定textField的text和label的text,这里的map其实就和RAC中的map是相似的,我不会立刻给你数据,我可以在里面先做完操作再给你。

关于throttle和debounce这两个其实都是去做了限制事件的接受为什么这么说?就拿上面的举例子,如果我们不想让文本框一改变上面的label就紧跟着改变的话,其实我们就可以用到这两个中的其中一个,这两个都可以去限制在某个时间间隔内我不去接受你文本框改变所产生的那个事件。

再结合一个小案例,就是通过在文本框输入点击提交按钮之后可以把文本框里面的每次提交内容都插入label中。

//创建一个可监听的数组,其实这里用普通的可变数组也是可以的
 
 //将数组中的元素以,来分隔开来,调用下面的joined方法的元素必须是String
 //将文本框里面的内容清空

首先看控制台打印也就是我们上面输出的数组经过插入


其中这里有一个注意点就是joined(separator: ",")这个方法,只能是数组里面的元素是String的时候才能使用,因为我们点进去看会看到下面的内容,这里面的Element==String就表示的是数组里面的元素的类型必须要是String

当然我们绑定textField的文本到label上面的文本,还有另外一种方式就是不经过map的这里为什么要

通过orEmpty?是因为其实就这里面将String?转为String处理,这样的话我们就不需要考虑String为nil的情况。在Rxswift中,对于所有字符串的监听都是转为orEmpty处理的

关于orEmpty其实框架里面也略微有解释



发在我们再点进去看,我们会发现它实现了ObserverType的协议,而实现ObserverType协议的是观察者对象,用于观察Observable发出的信号。所以我们这个label的就可以监听到textField信号的发出,然后去进行改变自己的值


还有一个那就是为什么这个textField是可被UILabel的rx.text观察的?而且它还可以被订阅。例如下面可以对它进行订阅


介绍下never,这个never就是创建出的Sequence是不会发出任何信号的,我们有的时候可以把它和其他信号进行concat,这样也能起到屏蔽信号的作用

empty,创建一个空的sequence,只会去发送一个completed的事件,在下面我们可以看到打印的value都是completed,这里应用场景的话可能会用于用户做了某件事情你只需要告诉它结果,就比如说下单了,订单完成还是没完成。

of就是创建出一个sequence,里面有很多事件信号,顺序发送出去,发送完成之后,然后再发送completed。这里of和from的区别其实就在于of是把它括号里面的1 2 3分别当做单独的事件,一个一个的拿出来发送,而from我们括号里面传入的是集合类,其实就是解析事件里面的元素,再把元素给一个个的去拿出来。


error,创建了一个可观察的序列,只发出error事件并结束,其他事件不会发出


这里再简单的介绍下Driver,Driver是驱动者,司机的意思,我们其实可以去理解为一个驱动者,在功能上它和被观察者Observable是类似的,它是可以和被观察者进行相互转换的,它会驱动着一个观察者,当它的序列中有事件的时候,被它驱动着的观察者就能进行相应的操作。一般我们会将一个Observable被观察者转换成Driver后再进行driver其实也就是开车操作做具体的事情,比如说绑定将某个值绑定到另一个值上面去。

    它的观察订阅是发生在主线程(UI线程)的,比如说我们将一个UI控件的值绑定到另外一个UI控件,用drive是默认在主线程上执行的,不然的话我们调用绑定方法的时候如果再子线程上执行,那么在更新UI的时候是会出现问题的

Observable有个隐式的规定,就是在一个信号处理完成之前,不会发送下一个信号

}

是我在 Github 上关注已久的一个项目,今天花点时间过了一下它的示例代码,感觉很有意思。

我主要是通过项目里的 进行学习和了解的,这种方式确实便捷高效。只需要把文档用 /*: */ 注释即可,直接用 Markdown 编写,简单方便。不过 Xcode7 中这种方式现在还不是很稳定,会有大量的空行,而且有个最大的问题就是阅读到中间然后切到其他文件再切回来的时候,阅读的进度条是从头开始的,并不能记录上次阅读的位置。心累。

下面是我的简单笔记,只是把学习过程中的收获记录下来,大部分内容来自于项目内的 playground 。注意!是很大部分!而且操场里图文并茂,很容易理解。所以,各位如果感兴趣,建议 clone 官方项目,跑个操场玩玩。

参考文献中罗列了我在学习过程中查阅的相关资料,可以作为补充阅读。

在进入正题之前,先看下项目里的 pleted 表示事件序列的完结。

  • .Error 同样表示完结,但是代表异常导致的完结。

(打个岔:协议命名,想起来上午汤哥在说的一段话:

never 是没有任何元素、也不会发送任何事件的空序列。

  1. sequenceOf 可以把一系列元素转换成事件序列。

     

    failWith 创建一个没有元素的序列,只会发送失败 (.Error) 事件。

    deferred 会等到有订阅者的时候再通过工厂方法创建 Observable 对象,每个订阅者订阅的对象都是内容相同而完全独立的序列。

    为什么需要 defferd 这样一个奇怪的家伙呢?其实这相当于是一种延时加载,因为在添加监听的时候数据未必加载完毕,例如下面这个例子:

    如果使用 deffered 则可以正常显示想要的数据:

    接下来是关于 Subject 的内容。 Subject 可以看做是一种代理和桥梁。它既是订阅者又是订阅源,这意味着它既可以订阅其他 Observable 对象,同时又可以对它的订阅者们发送事件。

    如果把 Observable 理解成不断输出事件的水管,那 Subject 就是套在上面的水龙头。它既怼着一根不断出水的水管,同时也向外面输送着新鲜水源。如果你直接用水杯接着水管的水,那可能导出来什么王水胶水完全把持不住;如果你在水龙头下面接着水,那你可以随心所欲的调成你想要的水速和水温。

    (好吧上面一段文档里没有,是我瞎掰的,如果理解错了还望打脸( ̄ε(# ̄)☆

}

上一篇文章内容比较多,文章简直是太长了,我都难以坚持看下去?,建议大家粗略读一遍就行了,用到的时候来查一下,慢慢地就掌握了。

这篇文章接着文章,主要来深入了解一些RxSwift实战中用到的一些重要知识点,这里面有很多自己的理解和思考,包含很多网上几乎收不到的内容,希望会是大家研究官方例子的一个重要参考资料,文章中不免会有些错误的地方,也请大家能多多留言交流,一起成长。这两篇文章过后,准备写实战教程,希望大家多多关注吧。还有文章在我里阅读更有感觉哦。let's go!

Rx系列的核心就是Observable Sequence这个相信大家心中已经有所了解了,这里不再啰嗦了,建议大家看看我都上一篇文章去了解一下。

当监听一个事件序列的时候,有消息事件来了,我们做某些事情。但是这个事件序列不再发出消息了,我们的监听也就没有什么存在价值了,所以我们需要释放我们这些监听资源,其实也就是每种编程语言中的内存资源释放。OC和Swift中也一样,在你不需要用某些变量的时候,你需要把这些变量所占用的内存空间释放掉。

释放某一个监听的时候我们可以手动调用释放方法,但是这个貌似一般不常用:

参数是一个闭包,其中闭包参数是E类型返回值是R类型,map函数的返回值是一个Observable类型。

Driver是啥东东?Driver功能很吊,讲解Driver之前我们现在看看下面的例子。

  • 首先创建一个可监听序列results,其中flatMapLatest怎么用我们下面讲

上面程序会有下面几个异常情况

  1. 如果上面fetchAutoCompleteItems出错了,那么他绑定的UI将不再收到任何事件消息
  2. 如果上面fetchAutoCompleteItems是在后台某个线程中运行的,那么事件绑定也是发生在后台某个线程,这样更新UI的时候会造成crash

当然针对上面问题我们也有解决方案,我们可以使用神器shareReplay(1)保证不会执行两次,可以使用observeOn()保证后面所有操作在主线程完成。

但是你也可以使用Driver

drive方法只能在Driver序列中使用,Driver有以下特点:1 Driver序列不允许发出error,2 Driver序列的监听只会在主线程中。所以Driver是转为UI绑定量身打造的东西。以下情况你可以使用Driver替换BindTo:

大家看官方Demo的时候,可能会迷惑为啥有的地方使用flatMapLatest为啥有些地方使用map呢?比如上面那个Driver所用的例子。

map函数,接受一个R类型的序列,返回一个R类型的序列,还是原来的序列

flatMap函数,接收一个O类型的序列,返回一个O.E类型的序列,也就是有原来序列里元素组成的新序列。

其实这里的map和flatMap在swift中的作用是一样的。map函数可以对原有序列里面的事件元素进行改造,返回的还是原来的序列。而flatMap对原有序列中的元素进行改造和处理,每一个元素返回一个新的sequence,然后把每一个元素对应的sequence合并为一个新的sequence序列。

我们使用map对序列中每一个元素进行了处理,返回的是一个元素,而使用flatMap需要返回的序列。那么使用map也返回一个序列看看。

看到结果会打印出每一个序列,下面我们使用merge()方法将这几个序列进行合并

合并为一个新序列后我们就可以正常打印元素了。下面看看使用faltMap()函数干这件事

看下对比是不是一样,这样子对比就清晰了吧。

  • map函数只能返回原来的那一个序列,里面的参数的返回值被当做原来序列中所对应的元素。
  • flatMap函数返回的是一个新的序列,将原来元素进行了处理,返回这些处理后的元素组成的新序列

flatMap函数在实际应用中有很多地方需要用到,比如网络请求,网络请求可能会发生错误,我们需要对这个请求过程进行监听,然后处理错误。只要继续他返回的是一个新的序列。

flatMapLatest其实就是flatMap的另一个方式,只发送最后一个合进来的序列事件。上面认证username是一个网络请求,我们需要对这个过程进行处理。

这个password不需要后台联网认证,只需要返回password符合不符合要求就行了,还是原来的序列就行了。

好了,相信大家对这俩货有了一个清晰的认识了吧。

UIBindingObserver是一个类,他的初始化方法中,有两个参数,第一个参数是一个元素本身,第一个参数是一个闭包,闭包参数是元素本身,还有他的一个属性。

好了,文章到这里也差不多了,这篇文章中没有实战教程,但绝对都是干货,也许在你专研官方demo的时候看不懂某个写法,看了这篇文章你就会豁然开朗了呢??

下一篇文章准备带大家一起实战,大家做好准备!!?

小伙伴们如果感觉文章可以,可以关注博主

小伙伴们也可以关注博主,探索博主内心世界?

}

我要回帖

更多关于 解决问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信