美文网首页
ReactiveObjC (一)

ReactiveObjC (一)

作者: wpf_register | 来源:发表于2020-06-07 23:20 被阅读0次

    RAC 框架中的主要类

    RACSignal

    信号类,一般表示将数据传递,只要有数据改变,信号内部就接收到数据,马上发出数据。

    • RACSignal 本身并不具备发送信号的能力,而是交给内部一个订阅者发出。

    • 默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变成热信号,值改变才会触发。

    • 调用信号 RACSingal 的subscribeNext 就能订阅

    #1.创建订阅者
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
       
       #3.发送信号,发送信号之前一定要先订阅信号
        每当有订阅者订阅信号,就会调用block。   
        [subscriber sendNext:@"1"];
           
       #如果不在发送数据,最好发送信号完成,
       内部会自动调用[RACDisposable disposable]取消订阅信号 
       [subscriber sendCompleted];
    
       # 当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号
        return [RACDisposable disposableWithBlock:^{
            
                # 执行完Block后,当前信号就不在被订阅了。
                NSLog(@"信号被销毁");
            }];
    }];
    
    #2. 订阅信号,才会激活信号 
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"--%@", x);
    }];
    
    

    分析:

    1. 创建信号方法内部会创建 RACDynamicSignal ,
      并持有:^RACDisposable *(id<RACSubscriber> _Nonnull subscriber)。

    2. 当订阅信号方法subscribeNext执行时,内部会创建一个RACSubscriber对象且持有nextBlock。
      进而做为参数,调用创建信号的Block。

    3. subscriber 调用 sendNext 方法时,会调用它的nextBlock方法

    所以RACSignal的处理流程就是
    创建信号的block会在订阅信号的时候调用
    订阅信号的block会在订阅者发布信息的时候调用

    RACSubject

    信号提供者,自己可以充当信号,又能发送信息。
    一般用来代替代理 需要先订阅

     #1.创建信号
     <创建数组,在信号对象中>
     RACSubject *subject = [RACSubject subject];
        
     #2.订阅信号
    <创建订阅者,将block 保存在订阅者中,将订阅者放在上面的数组中>
     [subject subscribeNext:^(id x) {
          // block调用时刻:当信号发出新值,就会调用.
          NSLog(@"第一个订阅者%@",x);
      }];
        
    #3.发送信号
    <遍历信号对象中的数组,取出订阅者对象,调用订阅者对旬中的Block>
    [subject sendNext:@"1"];
    
    [subject subscribeNext:^(id x) {
          // block调用时刻:当信号发出新值,就会调用.
          NSLog(@"第二个订阅者%@",x);
    }];
        
    

    分析:

    遍历信号对象中的数组,取出订阅者对象,调用订阅者对旬中的Block

    只有第一个订阅者能订阅到1

    RACReplaySubject

    RACSubject的子类,重复提供信号类,可以先订阅信号,也可以先发送信号
    如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复提供信号类。

    RACReplaySubject创建方法
    1.创建RACSubject
    2.订阅信号
    3.发送信号

    工作流程:
    1. 订阅信号,内部保存了订阅者,和订阅者相应的block
    2. 当发送信号的,遍历订阅者,调用订阅者的nextBlock

    3. 发送的信号会保存起来,当订阅者订阅信号的时候,会将之前保存的信号,
    一个个作用于新的订阅者,保存信号的容量由capacity决定,这也是有别于RACSubject的

    #1.创建信号
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
        
    # 2.发送信号
    [replaySubject sendNext:@1];
    [replaySubject sendNext:@2];
        
     # 3.订阅信号
     [replaySubject subscribeNext:^(id x) {
            
            NSLog(@"第一个订阅者接收到的数据%@",x);
     }];
        
    // 订阅信号
    [replaySubject subscribeNext:^(id x) {
            
            NSLog(@"第二个订阅者接收到的数据%@",x);
     }];
    
    
    //先发送后订阅
    第一个订阅者接收到的数据1
    第一个订阅者接收到的数据2
    第二个订阅者接收到的数据1
    第二个订阅者接收到的数据2
    
    # 1.创建信号
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
        
    # 2.订阅信号
    [replaySubject subscribeNext:^(id x) {
            
            NSLog(@"第一个订阅者接收到的数据%@",x);
     }];
        
    // 订阅信号
     [replaySubject subscribeNext:^(id x) {
            
            NSLog(@"第二个订阅者接收到的数据%@",x);
     }];
        
    #3.发送信号
    [replaySubject sendNext:@1];
    [replaySubject sendNext:@2];
    
    
    //先订阅后发送
    第一个订阅者接收到的数据1
    第二个订阅者接收到的数据1
    第一个订阅者接收到的数据2
    第二个订阅者接收到的数据2
    
    -(void)RACReplaySubject{
        
        RACReplaySubject *replaySubject = [RACReplaySubject subject];
        [replaySubject subscribeNext:^(id x) {
            NSLog(@" 1 %@",x);
        }];
        
        [replaySubject subscribeNext:^(id x) {
            NSLog(@"2 %@",x);
        }];
        [replaySubject sendNext:@7];
        [replaySubject sendNext:@6];
    
        [replaySubject subscribeNext:^(id x) {
            NSLog(@"3 %@",x);
        }];
      
    2021-03-02 18:38:48.556649+0800 **[14580:4162497]  1 7
    2021-03-02 18:38:48.556783+0800 **[14580:4162497]  2 7
    2021-03-02 18:38:48.556951+0800 **[14580:4162497]  1 6
    2021-03-02 18:38:48.557089+0800 **[14580:4162497]  2 6
    2021-03-02 18:38:48.557242+0800 **[14580:4162497]  3 7
    2021-03-02 18:38:48.557348+0800 **[14580:4162497]  3 6
    
    
    }
    

    RACCommand

    RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。

     #1.创建命令
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            
            
            NSLog(@"执行命令");
            
            # 创建空信号,必须返回信号,不能返回nil,可以返回空信号
            //return [RACSignal empty];
            
            #2.创建信号,用来传递数据
            return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                
                [subscriber sendNext:@"请求数据"];
                
                #数据传递完,最好调用sendCompleted,这时命令才执行完毕。
                [subscriber sendCompleted];
                
                return nil;
            }];
            
        }];
       
        #3.订阅RACCommand中的信号
        [[command execute:nil] subscribeNext:^(id  _Nullable x) {
             NSLog(@"%@",x);
       }];
    

    监听命令执行过程

       #监听命令是否执行完毕,默认会来一次,可以直接跳过,skip表示跳过第一次信号。
      [[command.executing skip:1] subscribeNext:^(id x) {
            
            if ([x boolValue] == YES) {
                // 正在执行
                NSLog(@"正在执行");
                
            }else{
                // 执行完成
                NSLog(@"执行完成");
            }
            
        }];
       // 执行命令
        [self.conmmand execute:@1];
    

    相关文章

      网友评论

          本文标题:ReactiveObjC (一)

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