最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的。在之前发表过一篇博文,名字叫做《iOS开发之浅谈MVVM的架构设计与团队协作》,大体上讲的就是使用Block回调的方式实现MVVM的。在写上篇文章时也知道有ReactiveCocoa这个函数响应式编程的框架,并且有许多人用它来更好的实现MVVM。所以在上篇博客发表后,有些同行给评论建议看一下ReactiveCocoa的东西,所以就系统的看了一下ReactiveCocoa的东西。不过有一点要说明的就是,不使用ReactiveCocoa是可以实现MVVM的,并非使用MVVM模式你就必须的使用ReactiveCocoa的东西,你可以使用KVO,Block,Delegate,Navigation等手段,而ReactiveCocoa更优雅的实现了这个过程。ReactiveCocoa就是一个响应式编程的框架,它会使MVVM每层之间交互起来更为方便,所以长和MVVM联系在一起。
一.函数响应式编程(Function Reactive Programming)
关于函数响应式编程的东西,我想引用国外这个ReactiveCocoa教学视频(视频链接https://vimeo.com/65637501)中的一张PPT来简单的说一下什么是函数响应式编程。那就直接上图,下图是上方视频链接的截图,很形象的解释了什么是函数响应式编程。简单的说下方c = a + b 定义好后,当a的值变化后,c的值就会自动变化。不过a的值变化时会产生一个信号,这个信号会通知c根据a变化的值来变化自己的值。b的值变化同样也影响c的值。下图很好的表达了这个思想。在此就不做赘述了。
二. ReactiveCocoa简介
先简单的介绍一下什么是ReactiveCocoa框架,然后通过实例好好的去搞一搞这个框架,最后就是如何在项目中使用了。关于ReactiveCocoa的理解一些博客(见本篇博客中的链接分享)中把ReactiveCocoa比喻成管道,ReactiveCocoa中的Signal就是管道中的水流。使用ReactiveCocoa可以方便的在MVVM各层之间架起沟通的管道,便于每层之间的交互。现在在我们做的工程中已经在使用ReactiveCocoa框架了,用起来的感觉是非常爽的,好用!
可以说ReactiveCocoa中核心是信号量机制,Signal在ReactiveCocoa中发挥着强大的不可代替的作用,可谓是ReactiveCocoa的灵魂所。Signal是可以携带一些对象和参数的,你可以获取该对象并且可以对该信号量携带的值进行map, filter等常用操作,操作后的值会和该信号量进行绑定。先简单的这么一说,后边的部分回详细的介绍如何让信号量发挥强大的作用。
ReactiveCocoa中对Block的使用可谓是淋漓尽致,如果对Block使用不熟的朋友可以补一下Block的东西,然后在回头看一下ReactiveCocoa的东西。关于ReactiveCocoa更多的东西,请参考Github上的链接(https://github.com/ReactiveCocoa/ReactiveCocoa)。
三. 在工程中引入ReactiveCocoa
1.你可以使用Github上的加入方式如下所示,本人感觉比较麻烦,就没有使用,采用的第二种方法(CocoaPods)。
2.上面的步骤难免有些麻烦,所以用CocoaPods更为便捷一些,Profile文件中的内容如下所示,我用的是2.5版本。3.0后就支持Swift了,因为我没有用Swift写东西,所以就用的是2.5版本,设置完Profile文件后,pod install即可。
你可以pod search ReactiveCocoa看一下版本,选择你需要的版本即可。
四.使用ReactiveCocoa
下方会通过一些简单的实例来介绍一下信号量机制和一些常用的方法。
1.引入相应的头文件
在工程中引入下方的头文件(建议在Pch文件中引入)就可以使用我们的ReactiveCocoa框架了
1 #import <ReactiveCocoa/ReactiveCocoa.h> 2 #import <ReactiveCocoa/RACEXTScope.h>
2. Sequence和Map
Sequence:队列,是ReactiveCocoa中引入的一个类型,它类似于数组,我们可以暂且把Sequence看做绑定信号量的数组吧。在OC中的NSArray可以通过rac_sequence方法转换成ReactiveCocoa中的Sequence,然后就可以调用处理信号的一些方法了。
参考以下实例代码:
(1)把NSArray通过rac_sequence方法生成RAC中的Sequence
(2)获取该Sequence对象的信号量
(3)调用Signal的Map方法,使每个元素的首字母大写
(4)通过subscribNext方法对其进行遍历输出
- (void)uppercaseString { , , ] rac_sequence]; 5 6 RACSignal *signal = sequence.signal; 7 8 RACSignal *capitalizedSignal = [signal map:^id(NSString * value) { 9 return [value capitalizedString]; 10 }]; 11 12 [signal subscribeNext:^(NSString * x) { , x); 14 }]; 15 16 [capitalizedSignal subscribeNext:^(NSString * x) { , x); 18 }]; 19 }