很早之前学习了RAC 的初级用法,随着经验的积累和不断地学习,对RAC思想有了更深的理解,也学到了很多关于RAC 的高级用法
bind 绑定/包装
这里的
bind
的主要作用属于包装,将信号返回的值包装成一个新的值是通过获取到信号返回的值,并包装成新的值, 再次通过信号返回给订阅者
bind方法使用步骤:
- 1.传入一个返回值
RACSignalBindBlock
的block
; - 2.描述一个
RACSignalBindBlock
类型的bindBlock作为block
的返回值; - 3.描述一个返回结果的信号,作为
bindBlock
的返回值.
- 注意:在
bindBlock
中做信号结果的处理
- 注意:在
[[_textField.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
return ^RACSignal*(id value, BOOL *stop){
// 做好处理,通过信号返回出去.
// 需要引入头文件 #import <ReactiveObjC/RACReturnSignal.h>
return [RACSignal return:[NSString stringWithFormat:@"hello: %@",value]];
};
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x); // hello: "x"
}];
flattenMap & Map 映射
flattenMap,Map
都是用于把源信号内容映射成新的内容
flattenMap
的底层实现是通过bind
实现的Map
的底层实现是通过flattenMap
实现的
flattenMap使用步骤:
- 1.传入一个
block
,block
类型是返回值RACStream
,参数value
; - 2.参数
value
就是源信号的内容,拿到源信号的内容做处理; - 3.包装成
RACReturnSignal
信号,返回出去。
[[_textField.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
return [RACSignal return:[NSString stringWithFormat:@"hello %@", value]];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x); // hello "x"
}];
Map使用步骤:
- 1.传入一个
block
,类型是返回对象,参数是value
; - 2.
value
就是源信号的内容,直接拿到源信号的内容做处理; - 3.把处理好的内容,直接返回就好了,不用包装成信号,返回的值,就是映射的值。
[[_textField.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
// 当源信号发出,就会调用这个block,修改源信号的内容
// 返回值:就是处理完源信号的内容。
return [NSString stringWithFormat:@"hello:%@",value];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x); // hello: "x"
}];
flatternMap和Map的区别
-
FlatternMap
中的Block
返回信号
-
Map
中的Block
返回对象
-
- 开发中,如果信号发出的值不是信号,映射一般使用
Map
- 开发中,如果信号发出的值不是信号,映射一般使用
-
- 开发中,如果信号发出的值是信号,映射一般使用
FlatternMap
- 开发中,如果信号发出的值是信号,映射一般使用
concat 合并
按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号
// 创建两个信号 signalA 和 signalB
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 把signalA拼接到signalB后,signalA发送完成,signalB才会被激活
[[signalA concat:signalB] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
注意:第一个信号必须发送完成,第二个信号才会被激活
then 下一个
用于连接两个信号,当第一个信号完成,才会连接then返回的信号
底层实现
- 1.使用concat连接then返回的信号
- 2.先过滤掉之前的信号发出的值
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
[subscriber sendCompleted];
return nil;
}] then:^RACSignal *{
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
}] subscribeNext:^(id x) {
// 只能接收到第二个信号的值,也就是then返回信号的值
NSLog(@"%@",x); // 2
}];
merge 合并
把多个信号合并为一个信号,任何一个信号有新值的时候就会调用
//创建多个信号
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 合并信号,任何一个信号发送数据,都能监听到.
RACSignal *mergeSignal = [signalA merge:signalB];
[mergeSignal subscribeNext:^(id x) {
NSLog(@"%@",x); //
}];
注意:只要有一个信号被发出就会被监听
zipWith 压缩
把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 压缩信号A,信号B
RACSignal *zipSignal = [signalA zipWith:signalB];
[zipSignal subscribeNext:^(id x) {
// x 为元祖
NSLog(@"%@",x); // (1, 2)
}];
注意:使用 zipWith 时,两个信号必须同时发出信号内容
combineLatest 结合
将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号
combineLatest 功能和 zipWith一样
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// 把两个信号组合成一个信号,跟zip一样,没什么区别
RACSignal *combineSignal = [signalA combineLatestWith:signalB];
[combineSignal subscribeNext:^(id x) {
NSLog(@"%@",x); // (1, 2)
}];
reduce 聚合
用于信号发出的内容是元组,把信号发出元组的值聚合成一个值
一般都是先组合在聚合
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@2];
return nil;
}];
// reduceblcok的返回值:聚合信号之后的内容。
RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id(NSNumber *num1 ,NSNumber *num2){
return [NSString stringWithFormat:@"%@ %@",num1,num2];
}];
[reduceSignal subscribeNext:^(id x) {
NSLog(@"%@",x); // 1 2
}];
filter 过滤
过滤信号,获取满足条件的信号
获取到位数大于6的值
[[_textField.rac_textSignal filter:^BOOL(NSString *value) {
return value.length > 6;
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x); // x 值位数大于6
}];
ignore 忽略
忽略掉指定的值
忽略掉值为 “666” 的信号
[[_textField.rac_textSignal ignore:@"666"] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
interval 定时
每隔一段时间发出信号
类似于 NSTimer
每隔1秒发送一次信号
[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
delay 延迟
延迟执行,类似于 GCD 的 after
这里的 delay
作用主要是延迟发送next
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
return nil;
}] delay:2] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];