RAC操做思想:
Hook(钩子)思想
RAC核心方法:bind
bind方法
假设想监听文本框的内容,而且在每次输出结果的时候,都在文本框的内容拼接一段文字“输出:”
[_textField.rac_textSignal subscribeNext:^(id x) {
NSLog(@"输出:%@",x);
}];
- 方式二:在返回结果前,拼接,使用RAC中bind方法作处理。
bind方法参数:须要传入一个返回值是RACStreamBindBlock的block参数
RACStreamBindBlock是一个block的类型,返回值是信号,参数(value,stop),所以参数的block返回值也是一个block。
RACStreamBindBlock:
参数一(value):表示接收到信号的原始值,还没作处理
参数二(*stop):用来控制绑定Block,若是*stop = yes,那么就会结束绑定。
返回值:信号,作好处理,在经过这个信号返回出去,通常使用RACReturnSignal,须要手动导入头文件RACReturnSignal.h。
bind方法使用步骤:
1.传入一个返回值RACStreamBindBlock的block。
2.描述一个RACStreamBindBlock类型的bindBlock做为block的返回值。
3.描述一个返回结果的信号,做为bindBlock的返回值。
注意:在bindBlock中作信号结果的处理。
底层实现:
1.源信号调用bind,会从新建立一个绑定信号。
2.当绑定信号被订阅,就会调用绑定信号中的didSubscribe,生成一个bindingBlock。
3.当源信号有内容发出,就会把内容传递到bindingBlock处理,调用bindingBlock(value,stop)
4.调用bindingBlock(value,stop),会返回一个内容处理完成的信号(RACReturnSignal)。
5.订阅RACReturnSignal,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。
>>>注意:不一样订阅者,保存不一样的nextBlock,看源码的时候,必定要看清楚订阅者是哪一个。
这里须要手动导入#import <ReactiveCocoa/RACReturnSignal.h>,才能使用RACReturnSignal。
[[_textField.rac_textSignal bind:^RACStreamBindBlock{
// 何时调用:
// block做用:表示绑定了一个信号.
return ^RACStream *(id value, BOOL *stop){
// 何时调用block:当信号有新的值发出,就会来到这个block。
// block做用:作返回值的处理
// 作好处理,经过信号返回出去.
return [RACReturnSignal return:[NSString stringWithFormat:@"输出:%@",value]];
};
}] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
映射(flattenMap,Map):
用于把源信号内容映射成新的内容
Map做用:把源信号的值映射成一个新的值
Map使用步骤:
1.传入一个block,类型是返回对象,参数是value
2.value就是源信号的内容,直接拿到源信号的内容作处理
3.把处理好的内容,直接返回就行了,不用包装成信号,返回的值,就是映射的值。
Map底层实现:
0.Map底层实际上是调用flatternMap,Map中block中的返回的值会做为flatternMap中block中的值。
1.当订阅绑定信号,就会生成bindBlock。
3.当源信号发送内容,就会调用bindBlock(value, *stop)
4.调用bindBlock,内部就会调用flattenMap的block
5.flattenMap的block内部会调用Map中的block,把Map中的block返回的内容包装成返回的信号。
5.返回的信号最终会做为bindBlock中的返回信号,当作bindBlock的返回信号。
6.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。
- (void)map
{
//1.建立信号
RACSubject *subject = [RACSubject subject];
//2.绑定信号
RACSignal *bindSignal = [subject map:^id(id value) {
//返回的类型就是你须要映射的值
return [NSString stringWithFormat:@"HMJ%@", value];
}];
//3.订阅信号
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
//4.发送数据
[subject sendNext:@"GQ"];
}
flattenMap:平铺地图
做用:用于信号中信号,把源信号的内容映射成一个新的信号,信号能够是任意类型
flattenMap使用步骤:
1.传入一个block,block类型是返回值RACStream,参数value
2.参数value就是源信号的内容,拿到源信号的内容作处理
3.包装成RACReturnSignal信号,返回出去。
flattenMap底层实现:
0.flattenMap内部调用bind方法实现的,flattenMap中block的返回值,会做为bind中bindBlock的返回值。
1.当订阅绑定信号,就会生成bindBlock。
2.当源信号发送内容,就会调用bindBlock(value, *stop)
3.调用bindBlock,内部就会调用flattenMap的block,flattenMap的block做用:就是把处理好的数据包装成信号。
4.返回的信号最终会做为bindBlock中的返回信号,当作bindBlock的返回信号。
5.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来
{
//1.建立信号
RACSubject *subject = [RACSubject subject];
//2.绑定信号
RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
//value:源信号发送的内容
value = [NSString stringWithFormat:@"HMJ%@", value];
//返回的信号:用来包装成修改内容值
return [RACReturnSignal return:value];
}];
//flattenMap中返回的是什么信号,订阅的就是什么信号
//订阅信号
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
//发送数据
[subject sendNext:@1];
}
FlatternMap和Map的区别
* 1.FlatternMap中的Block返回信号。
* 2.Map中的Block返回对象。
* 3.开发中,若是信号发出的值不是信号,映射通常使用Map
* 4.开发中,若是信号发出的值是信号,映射通常使用FlatternMap。
signalOfSignals用FlatternMap
// 建立信号中的信号
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[[signalOfsignals flattenMap:^RACStream *(id value) {
// 当signalOfsignals的signals发出信号才会调用
return value;
}] subscribeNext:^(id x) {
// 只有signalOfsignals的signal发出信号才会调用,由于内部订阅了bindBlock中返回的信号,也就是flattenMap返回的信号。
// 也就是flattenMap返回的信号发出内容,才会调用。
NSLog(@"%@aaa",x);
}];
// 信号的信号发送信号
[signalOfsignals sendNext:signal];
// 信号发送内容
[signal sendNext:@1];