ReactiveCocoa(RAC)学习笔记

1、ReactiveCocoa开发中常见用法

  • 代替代理:

rac_signalForSelector:用于替代代理。

  • 代替KVO :

rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变。

  • 监听事件:

    rac_signalForControlEvents:用于监听某个事件。

  • 代替通知:

rac_addObserverForName:用于监听某个通知。

  • 监听文本框文字改变:

rac_textSignal:只要文本框发出改变就会发出这个信号。

2、ReactiveCocoa高级用法

  • Map

Map作用:把源信号的值映射成一个新的值
###### Map使用步骤:
1.传入一个block,类型是返回对象,参数是value
2.value就是源信号的内容,直接拿到源信号的内容做处理
3.把处理好的内容,直接返回就好了,不用包装成信号,返回的值,就是映射的值。

Map使用场景:

1.服务端返回的数据不是你需要的,需要进行一次二次加工,使用 map就会很方便

      [[_textField.rac_textSignal map:^id(id value) {
        // 当源信号发出,就会调用这个block,修改源信号的内容
        // 返回值:就是处理完源信号的内容。
        return [NSString stringWithFormat:@"输出:%@",value];
    }] subscribeNext:^(id x) {

        NSLog(@"%@",x);
    }];
  • concat

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

concat使用场景:

1.在工作中,有这样的需求,可能一个页面要发送几个API,要求有一个API是依赖其他几个API,等到所有API都成功之后在刷新UI

    RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendCompleted];
        return nil;
    }];
    
    RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        [subscriber sendNext:@2];
        [subscriber sendCompleted];

        return nil;
    }];
    RACSignal *signal3 = [RACSignal createSignal:^RACDisposable *(id subscriber) {
        [subscriber sendNext:@"3"];
        [subscriber sendCompleted];

        return nil;
    }];
    
    //信号3依赖信号1和信号2
    RACSignal *signal = [[[RACSignal merge:@[signal1,signal2]]concat:signal3]   filter:^BOOL(id value) {
        return [value isKindOfClass:[NSNumber class]];
    }];
    
    [signal subscribeNext:^(id x) {
        NSLog(@"====%@",x);
    }completed:^{
        NSLog(@"所有都完事了");
    }];
log
2017-03-07 17:25:35.339 racDemo[61024:1544009] ====1
2017-03-07 17:25:35.340 racDemo[61024:1544009] ====2
2017-03-07 17:25:35.341 racDemo[61024:1544009] 所有都完事了

记得加         [subscriber sendCompleted];

  • Zip

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

   RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id subscriber) {
       [subscriber sendNext:@1];
       [subscriber sendCompleted];
       return nil;
   }];
   
   RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id subscriber) {
       [subscriber sendNext:@2];
       [subscriber sendCompleted];
       return nil;
   }];
   RACSignal *signal3 = [RACSignal createSignal:^RACDisposable *(id subscriber) {
       [subscriber sendNext:@"3"];
       [subscriber sendCompleted];
       return nil;
   }];

   RACSignal *signal = [RACSignal zip:@[signal1,signal2,signal3] reduce:^id(NSNumber *s1,NSNumber *s2,NSString *s3){
       return RACTuplePack(s1,s2,s3);
   }];
   
   [signal subscribeNext:^(RACTuple *tuple) {
       RACTupleUnpack(NSNumber *num1,NSNumber *num2,NSString *s3) = tuple;

       NSLog(@"%@%@%@",num1,num2,s3);
   }completed:^{
       NSLog(@"所有都完事了");
   }];
log
2017-03-07 17:38:57.227 racDemo[61197:1553408] 123
2017-03-07 17:38:57.227 racDemo[61197:1553408] 所有都完事了
tips:

1,记住要发送 [subscriber sendCompleted];
2,顺序不要乱了,每一个信号对应一个返回,顺序错了,返回的值也就不对应了
3,sendNext只会走一次,如果有两个sendNext,那么第二个发过来的值就不会生效
4,如果只要一个值,就没有必要RACTuplePack了
eg:
[subscriber sendNext:@"3"];
[subscriber sendNext:@"100"];
[subscriber sendCompleted];
同样代码,在后面多加上一个sendNext 输出结果如下
2017-03-07 17:44:17.808 racDemo[61350:1558976] 123
2017-03-07 17:44:17.808 racDemo[61350:1558976] 所有都完事了

  • combineLatest:

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

RACSignal combineLatest:<#(id)#> reduce:<#^id(void)reduceBlock#>
RACSignal combineLatest:<#(id)#>

用法和zip reduce差不多,但是每次有最新的都会回调
  • filter:

// 过滤:
// 每次信号发出,会先执行过滤条件判断.
[_textField.rac_textSignal filter:^BOOL(NSString *value) {
       return value.length > 3;
}];
  • doNext && doCompleted

[[[[RACSignal createSignal:^RACDisposable *(id subscriber) {
  [subscriber sendNext:@1];
  [subscriber sendCompleted];
  return nil;
}] doNext:^(id x) {
// 执行[subscriber sendNext:@1];之前会调用这个Block
  NSLog(@"doNext");;
}] doCompleted:^{
   // 执行[subscriber sendCompleted];之前会调用这个Block
  NSLog(@"doCompleted");;

}] subscribeNext:^(id x) {

  NSLog(@"%@",x);
}];

  • interval

[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) {

 NSLog(@"%@",x);
}];
  • then

then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号。


// then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号
// 注意使用then,之前信号的值会被忽略掉.
// 底层实现:1、先过滤掉之前的信号发出的值。2.使用concat连接then返回的信号
[[[RACSignal createSignal:^RACDisposable *(id subscriber) {

 [subscriber sendNext:@1];
 [subscriber sendCompleted];
 return nil;
}] then:^RACSignal *{
 return [RACSignal createSignal:^RACDisposable *(id subscriber) {
     [subscriber sendNext:@2];
     return nil;
 }];
}] subscribeNext:^(id x) {

 // 只能接收到第二个信号的值,也就是then返回信号的值
 NSLog(@"%@",x);
}];

你可能感兴趣的:(ReactiveCocoa(RAC)学习笔记)