ReactiveCocoa操作方法(映射,组合)

1.ReactiveCocoa操作方法之映射(flattenMap,Map)
flattenMap,Map:用于把原信号中的内容映射成新的内容
flattenMap的作用:把原信号的内容映射成一个新的信号,信号可以是任意的类型
flattenMap使用步骤:
1.传入一个block,block类型是返回值RACStream,参数value
2.参数value就是源信号的内容,拿到源信号的内容做处理
3.包装成RACReturnSignal信号,返回出去。

[[self.textfield.rac_textSignal flattenMap:^RACStream *(id value) {
//这个block什么时候调用:原信号发送数据的时候就会调用这个block
//block的作用:改变原信号的内容
return [RACReturnSignal return:value];
}] subscribeNext:^(id x) {
// 订阅绑定信号,每当原信号发送内容,做完处理就会调用这个block
NSLog(@"%@",x);
}];
flattenMap底层实现:
1.flattenMap内部调用bind方法实现的,flattenMap中block的返回值,会作为bind中bindBlock的返回值。
2.当订阅绑定信号,就会生成bindBlock。
3.当源信号发送内容,就会调用bindBlock(value, *stop)
4.调用bindBlock,内部就会调用flattenMap的block,flattenMap的block作用:就是把处理好的数据包装成信号。
5.返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号。
6.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。

Map:监听文本框的内容的改变,把结构重新映射成一个新的值
Map的作用:把原信号的值映射成一个新的值
Map使用步骤:
1.传入一个block,类型是返回对象,参数是value
2.value就是源信号的内容,直接拿到源信号的内容做处理
3.把处理好的内容直接返回,不用包装成信号,返回的值就是映射的值
// 创建信号
RACSubject *subject = [RACSubject subject];

RACSignal *signal = [subject map:^id(id value) {
    // 当原信号发送数据的时候就会来调用这个block,修改原信号的内容
    value  = @([value floatValue] +1.0);
    // 返回值就是修改后的原信号的内容
    return value;
}];

[signal subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

[subject sendNext:@"999”];

Map:底层实现
1.Map底层其实是调用flatternMap,Map中block中的返回的值会作为flatternMap中block中的值
2.当订阅绑定信号,就会生成bindBlock。
3.当源信号发送内容,就会调用bindBlock(value, *stop)
4.调用bindBlock,内部就会调用flattenMap的block
5.flattenMap的block内部会调用Map中的block,把Map中的block返回的内容包装成返回的信号。
6.返回的信号最终会作为bindBlock中的返回信号,当做bindBlock的返回信号
7.订阅bindBlock的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来。

FlatternMap和Map的区别:
1.FlatternMap中的Block返回信号
2.Map中的Block返回对象
3.开发中,如果信号发出的值不是信号,映射一般使用Map
4.开发中,如果信号发出的值是信号,映射一般使用FlatternMap

2.ReactiveCocoa操作方法组合
concat:按一定顺序拼接信号,当多个信号发出的时候有顺序的接受信号。
RACSubject *subjectA = [RACSubject subject];
RACSubject *subjectB = [RACSubject subject];

//把subjectA拼接到subjectB的时候只有subjectA发送完毕之后subjectB才会被激活
// 只需要订阅拼接之后的信号,不在需要单独拼接subjectA或者subjectB,内部会自动订阅
[[subjectA concat:subjectB] subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

[subjectA sendNext:@"subjectA发送完信号"];
// 第一个信号发送完成,第二个信号才会被激活
[subjectA sendCompleted];
[subjectB sendNext:@"subjectB发送完信号”];

concat底层实现:
1.当拼接信号被订阅,就会调用拼接信号的didSubscribe
 2.didSubscribe中,会先订阅第一个源信号(subjectA)
 3.会执行第一个源信号(subjectA)的didSubscribe
 4.第一个源信号(subjectA)didSubscribe中发送值,就会调用第一个源信号(subjectA)订阅者的nextBlock,通过拼接信号的订阅者把值发送出来.
5.第一个源信号(subjectA)didSubscribe中发送完成,就会调用第一个源信号(subjectA)订阅者的completedBlock,订阅第二个源信号(subjectB)这时候才激活(subjectB)
6.订阅第二个源信号(subjectB),执行第二个源信号(subjectB)的didSubscribe
7.第二个源信号(subjectA)didSubscribe中发送值,就会通过拼接信号的订阅者把值发送出来

then:用于连接两个信号,当第一个信号完成才会连接then返回的信号
使用then之前的信号会被忽略掉

RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"signalA发送完信号"];
//发送完毕
[subscriber sendCompleted];
return nil;

}];

RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"signalB发送完信号"];
    
    return nil;
}];

RACSignal *thensignal = [signalA then:^RACSignal *{
    return signalB;
}];

[thensignal subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

底层实现:1、先过滤掉之前的信号发出的值。2.使用concat连接then返回的信号

merge:把多个信号合并为一个信号,任何一个信号有新值时就会调用

RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"signalA发送完信号"];
   
    return  nil;
    
}];

RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"signalB发送完信号"];
    
    return nil;
}];

// 合并信号,任何一个信号发送数据都能在订阅中监听到
RACSignal *mergesignal = [signalA merge:signalB];

[mergesignal subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

底层实现:1.合并信号被订阅的时候就会遍历所有信号,并且发出这些信号
2.每发出一个信号,这个信号就会被订阅
3.也就是合并信号一被订阅,就会订阅里面所有的信号
4.只要有一个信号发出就会被监听

zipWith:把两个信号压缩成一个信号,只有当两个信号同时发出信号内容的时候,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件

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;
}];

//订阅中的数据和zip的顺序相关。
RACSignal *zipWithsignal = [signalA zipWith:signalB];
[zipWithsignal subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

底层实现:
1.定义压缩信号,内部就会自动订阅signalA和signalB
2.每当signalA或者signalB发出信号,就会判断signalA,signalB有没有发出个信号,有就会把最近发出的信号都包装成元组发出

combineLatest:将多个信号合并起来,并且拿到各个信号的最新值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号

//把两个信号组合成一个信号,跟zip一样,没什么区别
[[signalA combineLatestWith:signalB] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
底层实现:
1.当组合信号被订阅,内部会自动订阅signalA,被触发signalB必须两个信号都发出内容,才会被触发
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;
}];

// NSArray是遵守这个NSFastEnumeration协议的
//reduce中的block简介
//reduceblcok中的参数,有多少信号组合reduceblcok中就有多少参数,每个参数就是之前信号发出的内容,参数顺序和数组中的 参数一一对应
//reduceblcok的返回值:聚合信号之后的内容
RACSignal *reducesignal =  [RACSignal combineLatest:@[signalB,signalA] reduce:^id(NSString *str1,NSString *str2){
    return [NSString stringWithFormat:@"%@ --  %@",str1,str2];
}];
[reducesignal subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];

订阅聚合信号,每次有内容发出就会执行reduceblcok,把信号内容转换成reduceblcok返回的值。

不正确之处,欢迎补充
测试代码 https://github.com/CharType/ReactiveCocoaTest

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容