本demo详见github
1.RAC过滤
RACFilter_.m
#import "RACFilter_.h"
#import <ReactiveObjC.h>
@interface RACFilter_ ()
@property (nonatomic,strong)UITextField *textF;
@end
@implementation RACFilter_
- (void)viewDidLoad {
[super viewDidLoad];
self.textF = [[UITextField alloc]initWithFrame:CGRectMake(10, 100, 500, 60)];
self.textF.backgroundColor = [UIColor greenColor];
self.textF.placeholder = @"请输入内容";
[self.view addSubview:self.textF];
// [self skip];
// [self distinctUntilChanged];
// [self take];
// [self takeLast];
// [self takeUntil];
// [self ignore];
[self fliter];
}
-(void)skip{
//skip传入2 跳过前面两个值
//实际用处: 在实际开发中比如 后台返回的数据前面几个没用,我们想跳跃过去,便可以用skip
RACSubject *subject = [RACSubject subject];
[[subject skip:2] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
//3
}
-(void)distinctUntilChanged {
//如果当前的值跟上一次的值一样,就不会被订阅到
RACSubject *subject = [RACSubject subject];
[[subject distinctUntilChanged] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@2];
//1 2
}
-(void)take{
//take:可以屏蔽一些值,取面几个值---这里take为2 则只拿到前两个值
RACSubject *subject = [RACSubject subject];
[[subject take:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
//1 2
}
- (void)takeLast {
//takeLast:和take的用法一样,不过他取的是最后的几个值,如下,则取的是最后两个值
//注意点:takeLast 一定要调用sendCompleted,告诉他发送完成了,这样才能取到最后的几个值
RACSubject *subject = [RACSubject subject];
[[subject takeLast:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
[subject sendCompleted];
//2 3
}
-(void)takeUntil{
//takeUntil:---给takeUntil传的是哪个信号,那么当这个信号发送信号或sendCompleted,就不能再接受源信号的内容了(该信号也不发出)
RACSubject *subject = [RACSubject subject];
RACSubject *subject2 = [RACSubject subject];
[[subject takeUntil:subject2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号
[subject sendNext:@1];
[subject sendNext:@2];
[subject2 sendNext:@3]; //输出:1 2
// [subject2 sendCompleted]; //输出:1 2
[subject sendNext:@4];
}
- (void)ignore {
//ignore:忽略一些值
//ignoreValues:表示忽略所有的值
// 1.创建信号
RACSubject *subject = [RACSubject subject];
// 2.忽略一些值
RACSignal *ignoreSignal = [subject ignore:@2]; // ignoreValues:表示忽略所有的值
// 3.订阅信号
[ignoreSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 4.发送数据
[subject sendNext:@2];
[subject sendNext:@1];
[subject sendNext:@2];
//1 忽略了2
}
-(void)fliter{
// 只有当文本框的内容长度大于5,才获取文本框里的内容
[[self.textF.rac_textSignal filter:^BOOL(id value) {
// value 源信号的内容
return [value length] > 5;
// 返回值 就是过滤条件。只有满足这个条件才能获取到内容
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
}
@end
2.RAC映射
#import "Mapping_.h"
#import <ReactiveObjC.h>
#import <ReactiveObjC/RACReturnSignal.h>
@interface Mapping_ ()
@end
@implementation Mapping_
- (void)viewDidLoad {
[super viewDidLoad];
// [self map];
// [self flatMap];
// [self flattenMap2_way1];
// [self flattenMap2_way2];
[self flattenMap2_way3];
// [self flattenMap2_way4];
}
- (void)map {
// 创建信号
RACSubject *subject = [RACSubject subject];
// 绑定信号
RACSignal *bindSignal = [subject map:^id(id value) {
// 返回的类型就是你需要映射的值
return [NSString stringWithFormat:@"映射处理啦:%@", value]; //这里将源信号发送的“123” 前面拼接了ws:
}];
// 订阅绑定信号
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号
[subject sendNext:@"123"];
//映射处理啦:123
}
- (void)flatMap {
// 创建信号
RACSubject *subject = [RACSubject subject];
// 绑定信号
RACSignal *bindSignal = [subject flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// block:只要源信号发送内容就会调用
// value: 就是源信号发送的内容
// 返回信号用来包装成修改内容的值
NSString *changevalue = [NSString stringWithFormat:@"改变下值:%@",value];
return [RACReturnSignal return:changevalue];
}];
// flattenMap中返回的是什么信号,订阅的就是什么信号(那么,x的值等于value的值,如果我们操纵value的值那么x也会随之而变)
// 订阅信号
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送数据
[subject sendNext:@"123"];
//改变下值:123
}
- (void)flattenMap2_way1 {
// flattenMap 主要用于信号中的信号
// 创建信号
RACSubject *signalofSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[signalofSignals subscribeNext:^(id x) {
[x subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
}];
// 发送信号
[signalofSignals sendNext:signal];
[signal sendNext:@"123"];
}
- (void)flattenMap2_way2 {
// 创建信号
RACSubject *signalofSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[signalofSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
// 发送信号
[signalofSignals sendNext:signal];
[signal sendNext:@"123"];
}
- (void)flattenMap2_way3 {
// flattenMap 主要用于信号中的信号
// 创建信号
RACSubject *signalofSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
RACSignal *bignSignal = [signalofSignals flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value){
//value:就是源信号发送内容
return value;
}];
[bignSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号
[signalofSignals sendNext:signal];
[signal sendNext:@"123"];
}
//方式4:开发中常用的
- (void)flattenMap2_way4 {
// flattenMap 主要用于信号中的信号
// 创建信号
RACSubject *signalofSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[[signalofSignals flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
return value;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号
[signalofSignals sendNext:signal];
[signal sendNext:@"123"];
}
@end
3.RAC组合
#import "RACCombination_.h"
#import <ReactiveObjC.h>
@interface RACCombination_ ()
@property (nonatomic,strong)UITextField *accountF;
@property (nonatomic,strong)UITextField *pwdF;
@property (nonatomic,strong)UIButton *loginBtn;
@end
@implementation RACCombination_
- (void)viewDidLoad {
[super viewDidLoad];
self.accountF = [[UITextField alloc]initWithFrame:CGRectMake(10, 100, 200, 40)];
[self.view addSubview:self.accountF];
self.accountF.placeholder = @"账号输入";
self.pwdF = [[UITextField alloc]initWithFrame:CGRectMake(10, 200, 200, 40)];
[self.view addSubview:self.pwdF];
self.pwdF.placeholder = @"密码输入";
self.loginBtn = [[UIButton alloc]initWithFrame:CGRectMake(10, 300, 200, 40)];
[self.view addSubview:self.loginBtn];
self.loginBtn.backgroundColor = [UIColor redColor];
// [self combineLatest];
// [self zipWith];
// [self merge];
// [self then];
[self concat];
}
- (void)combineLatest {
RACSignal *combinSignal = [RACSignal combineLatest:@[self.accountF.rac_textSignal, self.pwdF.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){ //reduce里的参数一定要和combineLatest数组里的一一对应。
// block: 只要源信号发送内容,就会调用,组合成一个新值。
NSLog(@"%@ %@", account, pwd);
return @(account.length && pwd.length);
}];
// 订阅信号
// [combinSignal subscribeNext:^(id x) {
// self.loginBtn.enabled = [x boolValue];
// }]; // ----这样写有些麻烦,可以直接用RAC宏
RAC(self.loginBtn, enabled) = combinSignal;
}
- (void)zipWith {
//zipWith:把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元祖,才会触发压缩流的next事件。
// 创建信号A
RACSubject *signalA = [RACSubject subject];
// 创建信号B
RACSubject *signalB = [RACSubject subject];
// 压缩成一个信号
// **-zipWith-**: 当一个界面多个请求的时候,要等所有请求完成才更新UI
// 等所有信号都发送内容的时候才会调用
RACSignal *zipSignal = [signalA zipWith:signalB];
[zipSignal subscribeNext:^(id x) {
NSLog(@"%@", x); //所有的值都被包装成了元组
}];
// 发送信号 交互顺序,元组内元素的顺序不会变,跟发送的顺序无关,而是跟压缩的顺序有关[signalA zipWith:signalB]---先是A后是B
[signalA sendNext:@1];
[signalB sendNext:@2];
// <RACTwoTuple: 0x600001432780> (1,2)
}
// 任何一个信号请求完成都会被订阅到
// merge:多个信号合并成一个信号,任何一个信号有新值就会调用
- (void)merge {
// 创建信号A
RACSubject *signalA = [RACSubject subject];
// 创建信号B
RACSubject *signalB = [RACSubject subject];
//组合信号
RACSignal *mergeSignal = [signalA merge:signalB];
// 订阅信号
[mergeSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送信号---交换位置则数据结果顺序也会交换
[signalB sendNext:@"下部分"];
[signalA sendNext:@"上部分"];
//下部分
//上部分
}
// then --- 使用需求:有两部分数据:想让上部分先进行网络请求但是过滤掉数据,然后进行下部分的,拿到下部分数据
- (void)then {
// 创建信号A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"----发送上部分请求---afn");
//模拟网络请求
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendCompleted]; // 必须要调用sendCompleted方法!
});
return nil;
}];
// 创建信号B,
RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"--发送下部分请求--afn");
[subscriber sendNext:@"下部分数据"];
return nil;
}];
// 创建组合信号
// then;忽略掉第一个信号的所有值
RACSignal *thenSignal = [signalA then:^RACSignal *{
// 返回的信号就是要组合的信号
return signalsB;
}];
// 订阅信号
[thenSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
}
// concat----- 使用需求:有两部分数据:想让上部分先执行,完了之后再让下部分执行(都可获取值)
- (void)concat {
// 创建信号A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"----发送上部分请求---afn");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@"上部分数据"];
[subscriber sendCompleted]; // 必须要调用sendCompleted方法!
});
return nil;
}];
// 创建信号B,
RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"--发送下部分请求--afn");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@"下部分数据"];
});
return nil;
}];
// concat:按顺序去链接
//**-注意-**:concat,第一个信号必须要调用sendCompleted
// 创建组合信号
RACSignal *concatSignal = [signalA concat:signalsB];
// 订阅组合信号
[concatSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}
@end
4.RACBind
#import "RACBind_.h"
#import <ReactiveObjC.h>
#import <ReactiveObjC/RACReturnSignal.h>
@interface RACBind_ ()
@end
@implementation RACBind_
- (void)viewDidLoad {
[super viewDidLoad];
// 1.创建信号
RACSubject *subject = [RACSubject subject];
// 2.绑定信号
RACSignal *bindSignal = [subject bind:^RACSignalBindBlock{
// block调用时刻:只要绑定信号订阅就会调用。不做什么事情,
return ^RACSignal *(id value, BOOL *stop){
// 一般在这个block中做事 ,发数据的时候会来到这个block。
// 只要源信号(subject)发送数据,就会调用block
// block作用:处理源信号内容
// value:源信号发送的内容,
//这一行也可以注销哟(注销就是123哟)
value = @3; // 如果在这里把value的值改了,那么订阅绑定信号的值即41行的x就变了
NSLog(@"接受到源信号的内容:%@", value);
//返回信号,不能为nil,如果非要返回空---则empty或 alloc init。
return [RACReturnSignal return:value]; // 把返回的值包装成信号
};
}];
// 3.订阅绑定信号
[bindSignal subscribeNext:^(id x) {
NSLog(@"接收到绑定信号处理完的信号:%@", x);
}];
// 4.发送信号
[subject sendNext:@"123"];
}
//接受到源信号的内容:3
//接收到绑定信号处理完的信号:3
@end
友情链接:
网友评论