美文网首页
ReactiveCocoa 常见操作方法介绍

ReactiveCocoa 常见操作方法介绍

作者: rxdxxxx | 来源:发表于2016-02-17 12:25 被阅读385次

1.ReactiveCocoa 常见操作方法介绍

1.1 ReactiveCocoa操作须知

  • 所有信号(RACSignal)都可以进行操作处理, 因为所有操作都定义在RACStream.h中,而RACSignal继承RACStream.

1.2 ReactiveCocoa操作思想

  • 运用的是Hook思想, Hook是一种用于改变API执行结果的技术.
  • Hook的用处: 截获API调用的技术
  • Hook的原理: 在每次调用一个API返回结果之前, 先执行自己的方法, 改变结果的输出
  • RAC开发方式: RAC中核心开发方式, 也是绑定. 以前的开发方式是赋值, 而用RAC开发应该把重心放在绑定, 也就是说可以在创建一个对象的时候, 就绑定好以后想要做的事情, 而不是等赋值以后再去做事情
  • 例如: 把数据展示到控件上, 之前都是重写控件的setModel方法, 用RAC就可以在一开始创建控件的时候, 就绑定好数据.

1.3 ReactiveCocoa核心方法 Bind

接受到信号后, 可以做中间处理再返回数据

    // 1,绑定信号
    RACSubject *subject = [RACSubject subject];
    
    // 2,绑定信号
    RACSignal *bindSignal = [subject bind:^RACStreamBindBlock{
       
        return ^RACSignal *(id value, BOOL *stop){
          
            // block调用: 只要源信号发送数据, 就会调用block
            // block作用: 处理源信号内容
            // value: 源信号发送的内容
            
            NSLog(@"接收到的原信号的内容:%@",value);
            
            value = [NSString stringWithFormat:@"<经过处理的原信号:%@>",value];
            return [RACReturnSignal return:value];
        };
        
    }];
    
    
    // 3,订阅绑定信号
    [bindSignal subscribeNext:^(id x) {
       
        NSLog(@"接受绑定信号内容:%@",x);
        
    }];
    
    
    // 4,发送信号
    [subject sendNext:@"100"];

打印的内容

接收到的原信号的内容:100
接受绑定信号内容:<经过处理的原信号:100>

1.4 ReactiveCocoa操作方法 - 映射(flattenMap, Map)

  • flattenMap简单用法, 可以看到, flattenMap方法中, 返回值通过一个信号来返回,
   RACSubject *subject = [RACSubject subject];
    
    
    RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
        
        NSString *fixStr = [NSString stringWithFormat:@"RR : %@",value];

        
        return [RACReturnSignal return:fixStr];
        
    }];
    
    [bindSignal subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
        
    }];
    
    [subject sendNext:@"Jason"];

  • Map的简单使用, Map就是flattenMap的一个简化版本,也更实用一些,使用Map后返回一个新的bind信号, 订阅新的绑定信号, 接收到的订阅信息就是map处理后的信息了.

    RACSubject *subject = [RACSubject subject];
    
    
    RACSignal *bindSignal = [subject map:^id(id value) {
        
        return [NSString stringWithFormat:@"RR : %@",value];
        
    }];

    
    [bindSignal subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
        
    }];
    
    [subject sendNext:@"Jason"];


1.5 ReactiveCocoa操作方法 - 组合

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

皇帝 和 太子的关系, 皇帝驾崩了皇太子才能继位.

    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       
        [subscriber sendNext:@0];

        // 如果不设置订阅者已发送完成, 那么concatSignal不会接收到,信号B发送出的信号.
        //[subscriber sendCompleted];
        
        return nil;
    }];
    
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [subscriber sendNext:@1110];
        
        return nil;
        
    }];
    
    
    // 把signalA 拼接到signalB后, signalA发送完成, signalB才会被激活
    RACSignal *concatSignal = [signalA concat:signalB];

    
    
    // 以后只需要面对拼接信号开发
    // 订阅拼接的信号, 不需要单独订阅signalA,signalB
    // 内部会自动订阅
    // 注意: 第一个信号必须发送完成,第二个信号才会被激活
    [concatSignal subscribeNext:^(id x) {
        
        NSLog(@"%@", x);
        
    }];


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

    then的用法和concat很相似, 也更简化.下面用响应式写法实现.

    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       
        [subscriber sendNext:@0];
        
        [subscriber sendCompleted];
        
        return nil;
    }] then:^RACSignal *{
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
           
            [subscriber sendNext:@100];
            
            return nil;
        }];
        
    }] subscribeNext:^(id x) {
        
        // 只能接收到第二个信号的值, 也就是then返回信号的值.
        NSLog(@"%@",x);
        
    }];



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

    RACSubject *signalA = [RACSubject subject];
    
    RACSubject *signalB = [RACSubject subject];
    
    RACSignal *mergeSignal = [signalA merge:signalB];
    
    [mergeSignal subscribeNext:^(id x) {
       
        NSLog(@"%@", x);
        
    }];
    
    [signalB sendNext:@"信号B"];
    [signalA sendNext:@"信号A"];


打印信息:


信号B
信号A


底层实现:

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


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

夫妻关系-> 内容需要都完成,才能出发之后的事情.


    RACSubject *signalA = [RACSubject subject];
    
    RACSubject *signalB = [RACSubject subject];
    
    RACSignal *zipSignal = [signalA zipWith:signalB];
    

    [zipSignal subscribeNext:^(id x) {
       
        // x的类型的RACTuple
        // 其中内容的顺序是压缩时放入的顺序,
        NSLog(@"%@", x);
        
    }];
    
    // 需压缩的信号均发送信号, 订阅者才会接收到消息.
    [signalB sendNext:@"B"];
    [signalA sendNext:@"A"];

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


  • combineLatestWith: 将两个信号合并起来, 并且拿到各个信号的最新值, 必须每个合并的signal至少都有过一次sendNext, 才会触发合并的信号, 一般和reduce一起使用.

  • combineLatest (此方法为类方法) 合并多个信号,并且拿到各个信号的最新值, 必须每个合并的signal至少都有过一次sendNext, 才会触发合并的信号, 一般和reduce一起使用.

    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
    RACSubject *signalC = [RACSubject subject];
    RACSubject *signalD = [RACSubject subject];
    
    
    // reduce 的参数列表和
    [[RACSignal combineLatest:@[signalA ,signalB, signalC, signalD] reduce:^id(NSString *sA,NSString *sB,NSString *sC,NSString *sD){
        
        NSLog(@"%@%@%@%@",sA,sB,sC,sD);
        
        return @1;
        
    }] subscribeNext:^(id x) {
        
        
        NSLog(@"%@",x);
        
        
    }];
    
    
    
    [signalA sendNext:@"A"];
    [signalB sendNext:@"B"];
    [signalC sendNext:@"C"];
    [signalD sendNext:@"D"];


1.6 ReactiveCocoa操作方法 - 过滤

  • filter:过滤信号, 使用它可以获取满足条件的信号.
    [self.textField.rac_textSignal filter:^BOOL(NSString *value) {
       
        return value.length > 3;
        
    }];
  • ignore:忽略某些值的信号. 是filter的一种实现
    [[self.textField.rac_textSignal ignore:@"1"] subscribeNext:^(id x) {
        
        NSLog(@"%@", x);
        
    }];
  • distinctUntilChanged:当上一次的值和当前的值有变化就会发出信号, 否则被忽略
    // 过滤, 当上一次和当前值不一样,就会发出内容
    // 开发中, 刷新UI经常使用, 只有两次数据不一样才需要刷新
    [[self.textField.rac_textSignal distinctUntilChanged] subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
        
    }];
    
  • take:从开始一共去N次信号
    // 1,创建信号
    RACSubject *signal = [RACSubject subject];
    
    // 2,处理信号, 订阅信号
    [[signal take:1] subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
        
    }];
    
    // 3,发送信号
    [signal sendNext:@1];
    [signal sendNext:@2]; // 这次发送的内容,就不会接受到了.
    
  • takeLast:取最后N次的信号, 前提条件是,订阅者必须完成sendCompleted, 之后完成才知道一共有多少条信号发送

    // 1,创建信号
    RACSubject *signal = [RACSubject subject];
    
    // 2,处理信号, 订阅信号
    [[signal takeLast:2] subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
        
    }];
    
    // 3,发送信号
    [signal sendNext:@1];
    [signal sendNext:@2];
    [signal sendNext:@3];
    [signal sendNext:@4];
    [signal sendCompleted];
        
  • takeUntil:只要传入的信号发送完成或者发送任何数据, 那么就不会接受原信号发送的内容
    // 1,创建信号
    RACSubject *subject = [RACSubject subject];
    RACSubject *signal = [RACSubject subject];
    
    // 2,处理信号, 订阅信号
    [[subject takeUntil:signal] subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
        
    }];
    
    // 3,发送信号
    [subject sendNext:@1];
    [subject sendNext:@2];
    
    [signal sendCompleted];
    // [signal sendNext:@2];
    // [signal sendError:nil]; // 发送error不会阻止原信号.

    [subject sendNext:@3];
    [subject sendNext:@4];
    [subject sendCompleted];
        
  • skip:(NSUInteger):跳过几个信号,不接受。


    // 1,创建信号
    RACSubject *subject = [RACSubject subject];
    
    // 2,处理信号, 订阅信号
    [[subject skip:2] subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
        
    }];
    
    // 3,发送信号
    [subject sendNext:@1];
    [subject sendNext:@2];
    
    [subject sendNext:@3];
    [subject sendNext:@4];


  • switchToLatest:用于signalOfSignals(信号的信号),有时候信号也会发出信号,会在signalOfSignals中,获取signalOfSignals发送的最新信号。
RACSubject *signalOfSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];

// 获取信号中信号最近发出信号,订阅最近发出的信号。
// 注意switchToLatest:只能用于信号中的信号
[signalOfSignals.switchToLatest subscribeNext:^(id x) {

   NSLog(@"%@",x);
}];
[signalOfSignals sendNext:signal];
[signal sendNext:@1];


相关文章

  • ReactiveCocoa 常见操作方法介绍

    1.ReactiveCocoa 常见操作方法介绍 1.1 ReactiveCocoa操作须知 所有信号(RACSi...

  • ReactiveCocoa总结二

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知 所有的信号(RACS...

  • ReactiveCocoa进阶篇

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知所有的信号(RACSi...

  • ReactiveCocoa 常见用法

    1.ReactiveCocoa常见操作方法介绍。1.1 ReactiveCocoa操作须知所有的信号(RACSig...

  • ReactiveCocoa练习

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知 所有的信号(RACS...

  • ReactiveCocoa进阶

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知所有的信号(RACSi...

  • ReactiveCocoa

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知所有的信号(RACSi...

  • ReactiveCocoa实战

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知所有的信号(RACSi...

  • ReactiveCocoa(FRP)-进阶篇

    1.ReactiveCocoa常见操作方法介绍1.1 ReactiveCocoa操作须知所有的信号(RACSign...

  • OC之ReactiveCocoa进阶

    1.ReactiveCocoa常见操作方法介绍。 1.1 ReactiveCocoa操作须知 所有的信号(RACS...

网友评论

      本文标题:ReactiveCocoa 常见操作方法介绍

      本文链接:https://www.haomeiwen.com/subject/jncmkttx.html