MVVM+RAC简单使用教程
既然是简单使用那就不讲那些概念了。什么是MVC、MVP、MVVM这些就忽略啦!很多大神写了很多,有关他们的优缺点都写的非常的好,我就没必要再写一遍了。
直接开始写怎么开始一个 MVVM+RAC 的教程了。
我喜欢在写代码的时候先写思路,这样就顺便把注释也写了。
写Demo和下厨是一样一样的,得有先材料。
那么写这个也要准备一下材料:
1. 导入ReactiveCocoa框架。
这里没有两个版本一个OC和一个Swift版本。如果你的项目是OC的你没必要在把Swift的下载下来,而且还要配置不然工程会报错。
Swift:
use_frameworks!
target 'Target名称' do
pod 'ReactiveCocoa', '5.0.0-alpha.3'
end
OC:
use_frameworks!
target 'Target名称' do
pod 'ReactiveObjC', '~> 2.1.0'
end
我用的是OC版本,网络我用到了AFNetworking
use_frameworks!
target 'Target名称' do
pod 'ReactiveObjC', '~> 2.1.0'
pod 'AFNetworking', '~> 3.0'
end
2. New一个MVVM项目 我们就由一个简单的登录业务模块开始,然后跳转到一个网络加载的数据列表页,点击Cell跳转页面。这样一个小的Demo,也比较容易去理解整个MVVM和RAC的使用。
新建工程后:
2.1 新建一个MVVM-prefix.pch 文件
#import <ReactiveObjC/ReactiveObjC.h>
#import <AFNetworking/AFNetworking.h>
因为是Demo所以就这么写了。
2.2新建一个 model 用来当信号里的属性 用来监听信号
#import <Foundation/Foundation.h>
@interface AccountModel : NSObject
@property(nonatomic,strong)NSString *userName;
@property(nonatomic,strong)NSString *pwd;
@end
2.3 新建一个 ViewModel
#import <Foundation/Foundation.h>
#import "AccountModel.h"
@interface LoginViewModel : NSObject
@property(nonatomic,strong)AccountModel *account;
@property(nonatomic,strong)RACSignal *listeningSignal;
@property(nonatomic,strong)RACSubject *btnColorSubject;
@property(nonatomic,strong)RACCommand *loginCommand;
@property(nonatomic,strong)UINavigationController *nav;
@end
#import "LoginViewModel.h"
#import "ListViewController.h"
@implementation LoginViewModel
-(AccountModel*)account{
if (!_account) {
_account = [[AccountModel alloc]init];
}
return _account;
}
-(instancetype)init{
if (self=[super init]) {
[self initalBind];
}
return self;
}
-(void)initalBind{
////创建信号 通过combinelatest 讲两个型号组合一起 通过一个宏RACObserve 来观察Account 里面的 属性的变化
_listeningSignal = [RACSignal combineLatest:@[RACObserve(self.account, userName),RACObserve(self.account, pwd)] reduce:^id(NSString *account,NSString *pwd){
////这里就判断 发送哪个信号出去 用来改变颜色
// if (account.length && pwd.length) {
// [self.btnColorSubject sendNext:@1];
// } else {
// [self.btnColorSubject sendNext:@2];
// }
return @(account.length&&pwd.length);
}];
////创建一个RACCommand 事件
// 1.signalBlock必须要返回一个信号,不能传nil.
// 2.如果不想要传递信号,直接创建空的信号[RACSignal empty];
// 3.RACCommand中信号如果数据传递完,必须调用[subscriber sendCompleted],这时命令才会执行完毕,否则永远处于执行中。
// 4.RACCommand需要被强引用,否则接收不到RACCommand中的信号,因此RACCommand中的信号是延迟发送的。
_loginCommand = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
RACSignal *loginSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
////这里就是模拟网络的一个block
[Netwrok getData:^(NSString *str) {
[subscriber sendNext:str];
[subscriber sendCompleted];
}] ;
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号销毁");
}];
}];
return loginSignal;
}];
////这里就是订阅command 里面的信号 根据不同信号来跳转 和 处理业务
[_loginCommand.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);