RAC结合MVVM的使用

       首先来对比一下常用的几种架构,这里列举三种,MVC,MVP,MVVM架构,MVC架构属于最经典的一种架构,M相当于Model层,负责处理数据相关的操作,V属于View层,负责各种UI的展示和用户交互,C属于Controller控制器,属于协调M层和V层,对于简单的项目来说,使用MVC架构模式已经绰绰有余,但是随着项目的不断变大,功能不断增多,参与项目的人员的更替,会发现,大量的业务逻辑是放在C层,而且不同人的编程习惯不一样,当复杂的业务逻辑加上庞大的功能划分叠加在一起的时候,会发现我们的C层早已臃肿不堪,摇摇欲坠了,这个时候代码想要前进,唯一的办法就是替换当前架构模式。

      这里就先引入MVP架构,百度一下会看到这样一句话:MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示,这个架构其实是多出了一层(P层)来帮助C层处理业务逻辑,这样做的好处显而易见,C层肩上的担子明显轻了很多,而且很多业务逻辑可以丢到P层来处理,一般项目可以使用这中架构模式,但是随着开发的脚步不断向前迈进,你会发现P层和C层过于亲密,频繁的交互高度耦合,当我们的需求变更时,P层也更作开始大变更,对于大型项目或者拓展性要求较高的项目,MVP架构明显不能完成胜任,接下来,我们一起看看今天的重点,MVVM架构模式。

    MVVM架构,继续百度吧,MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。进一步百度WPF,可以看到在技术层面,WPF带来了 诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性,其实说到底就是一种信号绑定数据的模式,所有的数据都在信号里面执行,再由信号传递出来,优点很明显,低耦合,可重用,没个人可以写自己的ViewModel模块而不影响别人的代码。

之前一篇文章已经讲了一部分的RAC用法,接下来我们继续进入RAC的使用,当你掌握它之后,我敢相信你已经深深爱上了RAC,因为它太神奇了,来,干!!!!

应用场景: 当我们请求到数据后,如果几个地方都需要用到这个数据,如何避免多次使用,但请求就只有一次?

// 1. 创建信号                                                                                                               RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {

// 请求数据

NSLog(@"请求数据");

// 发送数据

[subscriber sendNext:@"发送数据"];

return nil;

}];

// 2.转换信号

RACMulticastConnection *connection = [signal publish];

// 3.开始订阅

[connection.signal subscribeNext:^(id  _Nullable x) {

NSLog(@"A处理数据%@",x);

}];

[connection.signal subscribeNext:^(id  _Nullable x) {

NSLog(@"B处理数据%@",x);

}];

// 连接

[connection connect];

应用场景二: RACComand,这个类极大的帮我们优化的开发过程中的逻辑,流程:发送指令--->接收指令--->请求数据--->发送数据---->订阅数据(还可以监听事件的执行状态)

// 1.创建命令    RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {        // input: 就是下面的输入的指令        NSLog(@"%@",input);        // 返回一个信号        return [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {

// 发送数据

[subscriber sendNext:@"执行完命令后,产生的数据"];

// 《如果要监听事件的状态,必须执行事件完成状态》

[subscriber sendCompleted];

return nil;

}];

}];

// 监听事件: 获取命令状态

[command.executing subscribeNext:^(NSNumber * _Nullable x) {

NSLog(@"%@",x);

if ([x boolValue]) {

NSLog(@"正在执行");

} else {

NSLog(@"已经结束和还没开始做");

}

}];

// 执行

RACSignal *signal = [command execute:@"执行"];

// 订阅

[signal subscribeNext:^(id  _Nullable x) {

NSLog(@"接收到数据了,%@",x);

}];

应用场景三: 绑定:bind

// 1.创建信号

RACSubject *subject = [RACSubject subject];

// 2.绑定信号

RACSignal *bindSignal = [subject bind:^RACSignalBindBlock _Nonnull{

return ^RACSignal *(id value,BOOL *stop) {

// value 就是“发送原始数据”

NSLog(@"%@",value);

// 应用场景: 可以在这里做字典转模型

// 返回空信号

//            return [RACSignal empty];

return [RACReturnSignal return:value];

};

}];

// 3. 订阅信号

[bindSignal subscribeNext:^(id  _Nullable x) {

NSLog(@"%@",x);

}];

// 4.发送

[subject sendNext:@"发送原始数据"];

其他场景:

顺序组合 : concat 比较类似于串行队列

返回最后的信号 : then 

压缩信号 : zip 只有当多个信号都有发送数据时才会调用

组合 : combineLatest 同时监听多个信号

合并 : merge 任一信号发送数据就会执行,类似并行队列

这里就不上代码了,只需要知道有这些个类型,及用法,到时候根据需要自行百度就好。

最后,就如何结合MVVM实际用法,简单谈下方法,由于C层只要求展示UI和用户交互外,可以处理非常简单的逻辑外,其余的事情我们直接交给ViewModel层来处理,可以在ViewModel里面设置各种信号属性,同时让C层持有ViewModel作为属性,在事件需要处理时,使用RACComand或者RACSubject或者RACSignal来将事件转化成信号。

另外需要特别主要的是:

1.输入框的信号(比如:让ModelView的属性变化通过RAC宏来绑定C层的输入框的信号)

2.RAC宏的优越性

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容