1、特点:
在事件发生的时候立刻做出反应。
2、以下操作都是响应式编程:
Target
Delegate
KVO
通知
时钟
网络异步回调
3、目的:
接管事件的监听
4、注意(坑):
(1)RAC最大的坑是循环引用
(2)多人开发中,确保所有人的代码风格一致
(3)个人开发,要注意版本对应的语言:
2.5以下全都是OC,
3.0是OC末代,
4.0开始swift2.0
5.0开始支持swift3.0
6.0开始支持swift4.1 等等,
具体看github的介绍吧。
初识
//RACSignal 信号
/*
创建信号
订阅信号
发送信号
*/
//创建
RACSignal *sigal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"创建了信号");
//发送
[subscriber sendNext:@"this is RAC"];
NSLog(@"发送了信号");
return nil;
}];
//订阅
[sigal subscribeNext:^(id _Nullable x) {
//x 信号的内容
NSLog(@"%@",x);
NSLog(@"订阅了信号");
}];
/*
2017-10-10 15:14:25.875726+0800 RAC[23884:952541] 创建了信号
2017-10-10 15:14:25.875982+0800 RAC[23884:952541] this is RAC
2017-10-10 15:14:25.876127+0800 RAC[23884:952541] 订阅了信号
2017-10-10 15:14:25.876640+0800 RAC[23884:952541] 发送了信号
*/
/*
创建信号必须先订阅
订阅信号必须先发送
*/
KVO
[RACObserve(self.person, name) subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
Target
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
// x is btn
NSLog(@"%@",x);
}];
Delegate
[[self.field rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x);
}];
通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"qwe" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@",x);
}];
组合 (登录为例)
//x is 0 or 1
// so
RAC(self.btn,enabled) =
[[RACSignal combineLatest:@[self.field.rac_textSignal,self.field2.rac_textSignal]] reduceEach:^id _Nullable(NSString *account ,NSString *pwd){
return @(account.length && account.length);
}];
//命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"密码加密");
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"请求登录"];
[subscriber sendCompleted]; //发出命令完成
return nil;
}];
}];
//命令执行的过程
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]) {
NSLog(@"显示等待....");
}else{
NSLog(@"移动等待");
}
}];
//拿到最新的信号
[command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
//执行命令
[command execute:nil];
}];
MVVM架构下优化组合信号
#import <Foundation/Foundation.h>
#import "ReactiveObjC.h"
@interface LoginViewModel : NSObject
@property (nonatomic,strong) RACSignal *loginBtnEnableSignal;
@property (nonatomic,strong) RACCommand *loginCommand;
@property (nonatomic,strong) NSString *account;
@property (nonatomic,strong) NSString *pwd;
@end
//
// LoginViewModel.m
// RAC
//
// Created by WiKi on 2017/10/18.
// Copyright © 2017年 wiki. All rights reserved.
//
#import "LoginViewModel.h"
@implementation LoginViewModel
- (instancetype)init{
self =[super init];
if (self) {
[self setUp];
}
return self;
}
- (void)setUp{
_loginBtnEnableSignal =
[[RACSignal combineLatest:@[RACObserve(self, account),RACObserve(self, pwd)]] reduceEach:^id _Nullable(NSString *account ,NSString *pwd){
return @(account.length && account.length);
}];
//command
//命令
self.loginCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"密码加密");
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"请求登录"];
[subscriber sendCompleted]; //发出命令完成
return nil;
}];
}];
//命令执行的过程
[[self.loginCommand.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]) {
NSLog(@"显示等待....");
}else{
NSLog(@"移动等待");
}
}];
//拿到最新的信号
[self.loginCommand.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
}
@end
RAC(self.loginViewModel,account) = self.field.rac_textSignal;
RAC(self.loginViewModel,pwd) = self.field2.rac_textSignal;
RAC(_btn,enabled) = self.loginViewModel.loginBtnEnableSignal;
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
//执行命令
[_loginViewModel.loginCommand execute:nil];
}];