ReactiveObjC (一)

2020-06-07  本文已影响0人  wpf_register

RAC 框架中的主要类

RACSignal

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

#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];
上一篇下一篇

猜你喜欢

热点阅读