iOS-ReactiveObjC 的高级使用(二)

来源:互联网 发布:淘宝小二电话 编辑:程序博客网 时间:2024/06/06 02:21

很早之前学习了RAC 的初级用法,随着经验的积累和不断地学习,对RAC思想有了更深的理解,也学到了很多关于RAC 的高级用法


bind 绑定/包装

这里的bind的主要作用属于包装,将信号返回的值包装成一个新的值

是通过获取到信号返回的值,并包装成新的值, 再次通过信号返回给订阅者

这里写图片描述

bind方法使用步骤:

  • 1.传入一个返回值RACSignalBindBlockblock;
  • 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.传入一个blockblock类型是返回值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的区别

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

concat 合并

按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号

这里写图片描述

// 创建两个信号 signalA 和 signalBRACSignal *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,信号BRACSignal *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);}];