zoukankan      html  css  js  c++  java
  • ReactiveObjC

    简介:

    RAC 指的就是 RactiveCocoa ,是 Github 的一个开源框架,能够帮我们提供大量方便的事件处理方案,让我们更简单粗暴地去处理事件,现在分为 ReactiveObjCReactiveSwift ,两个框架的功能使用相似.

    RAC 的核心思想:创建信号 - 订阅信号 - 发送信号.

    Podfile文件:

    1 platform :ios, '10.0'
    2 target "RAC" do
    3 pod 'ReactiveObjC', '~> 3.1.0'
    4 use_frameworks!
    5 end

    1. RACSignal 信号(主线程中执行)

     1 //    创建信号
     2     RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
     3 //        发送信号
     4         [subscriber sendNext:@"发送信号"];
     5         return nil;
     6     }];
     7     
     8     /* 订阅信号 */
     9     RACDisposable *disposable = [signal subscribeNext:^(id  _Nullable x) {
    10         
    11         NSLog(@"信号内容:%@", x);
    12     }];
    13     
    14 //    取消订阅
    15     [disposable dispose];

     结果:


    2. RACSubject 信号(主线程中执行)

     通常用来代替代理,有了它,就不必要定义代理了。

     1 //    创建信号
     2     RACSubject *subject = [RACSubject subject];
     3 //    订阅信号(通常在别的视图控制器中订阅,与代理的用法类似
     4     [subject subscribeNext:^(id  _Nullable x) {
     5         NSLog(@"信号内容:%@", x);
     6     }];
     7     [subject subscribeNext:^(id _Nullable x) {
     8 //    block调用时刻:当信号发出新值,就会调用.
     9          NSLog(@"第二个订阅者%@",x);
    10     }];
    11 //    发送信号
    12     [subject sendNext:@"发送信号"];

    结果:


    3. RACTuple 元组(主线程中执行)

    RAC 的元祖,跟我们 OC 的数组其实是一样的,它其实就是封装了我们 OC 的数组。

    3.1

    1 //    把值包装成 元组
    2     RACTuple * tuple = RACTuplePack(@"abc",@"def",@"ghj");
    3 //    解析元组
    4 //    RACTupleUnpack(NSString * a , NSString * b , NSString * c) = tuple ;
    5     NSLog(@"RACTuple 元组包装: pack = %@ ",tuple);

     结果:

    3.2 NSDictionary 元组 , 将字典里面的每一对 keyValue 列举出来(开了一个新的线程,异步列举)

    1     NSDictionary * dicTuple = @{@"name":@"Jakey" , @"age":@18 , @"student":@(YES)};
    2     [dicTuple.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
    3         NSString * key = [(RACTuple *)x objectAtIndex:0];
    4         id value = [(RACTuple *)x objectAtIndex:1];
    5         NSLog(@"NSDictionary 元组使用 = %@ , key = %@ , value = %@ , thread = %@",x,key,value,[NSThread currentThread]);
    6     }completed:^{
    7         NSLog(@"NSDictionary 元组使用 completed , thread = %@",[NSThread currentThread]);
    8     } ];

    结果:

    3.3 NSArray 元组 ,将数组内的所有数据列举出来 (异步列举)

    1  NSArray * array = @[@"klr",@"nop",@"rst"];
    2     [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
    3         NSLog(@"NSArray 元组 x = %@ , thread = %@",x,[NSThread currentThread]);
    4     }error:^(NSError * _Nullable error) {
    5         NSLog(@"NSArray 元组 error = %@",error);
    6     } completed:^{
    7         NSLog(@"NSArray 元组 completed ,thread = %@",[NSThread currentThread]);
    8     }];

    结果:

    3.4 异步列出 数组 或 字典 内容

    1     NSArray * array = @[@"重装炮台111111111",@"追击潜能222222222222",@"警戒地雷333333333"];
    2     NSArray * mapArray = [[array.rac_sequence map:^id _Nullable(id  _Nullable value) {
    3         NSLog(@"value = %@ , thread = %@",value,[NSThread currentThread]);
    4         return [value stringByAppendingString:@" temp"];
    5     }] array] ;
    6     NSLog(@"===== %@", mapArray);

    结果:


    4. RACReplaySubject 先发送 再订阅(主线程中执行)

     先发送 再订阅 (这个比较 实用 ,可以在不知道什么时候发送信号的情况下准确的接收到信号)(主线程中执行)

     1 //    Capacity 事先预指订阅的个数,里面是动太数组
     2     RACReplaySubject * replaySubject = [RACReplaySubject replaySubjectWithCapacity:2];
     3     
     4 //    发送
     5     [replaySubject sendNext:@"RACReplaySubjectDome 先发送 1"];
     6     [replaySubject sendNext:@"RACReplaySubjectDome 先发送 2"];
     7     [replaySubject sendCompleted];
     8     
     9 //    订阅
    10     [replaySubject subscribeNext:^(id  _Nullable x) {
    11         NSLog(@"subscribeNext:x = %@ error completed , thread  = %@",x,[NSThread currentThread]);
    12     } error:^(NSError * _Nullable error) {
    13         NSLog(@"error = %@ , thread = %@",error,[NSThread currentThread]);
    14     } completed:^{
    15         NSLog(@"completed ! , thread = %@",[NSThread currentThread]);
    16     }];
    17     
    18 //    延时订阅,一样可以接收到信号
    19     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    20         [replaySubject subscribeNext:^(id  _Nullable x) {
    21             
    22             NSLog(@"subscribeNext: x = %@, thread = %@",x,[NSThread currentThread]);
    23         }];
    24     });

    结果:


    5. RACMulticastConnection :广播连接(将 RACSignal 转成 RACMulticastConnection , block 在 main 主线程执行)

     1 //  网络数据加载方法
     2 -(void)loadDataFromNetwork:(void(^)(NSArray * dataArr))resultBlock
     3 {
     4     NSLog(@"loadDataFromNetwork selector thread = %@",[NSThread currentThread]);
     5     
     6     resultBlock(@[@"temp = 1" , @"temp = 2" , @"temp = 3"]);
     7 }
     8 
     9 
    10 
    11 
    12 - (RACSignal *)returnSignal {
    13     //      不能解决 _view ( === self->_view , 这样就无法解决强引用的问题)
    14 //      __weak typeof(self) weakSelf = self ;
    15     
    16 //      无论哪种用法都可以解决强引用问题
    17         @weakify(self);
    18     
    19         RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    20 //        @weakify(self) 配套使用
    21         @strongify(self);
    22         NSLog(@"connection createSignal , thread = %@",[NSThread currentThread]);
    23         
    24         [self loadDataFromNetwork:^(NSArray *dataArr) {
    25             NSLog(@"loadDataFromNetwork block dataArr = %@ , thread = %@",dataArr , [NSThread currentThread]);
    26 //        发送信号
    27             [subscriber sendNext:dataArr];
    28             [subscriber sendCompleted]; //信号发送结束
    29         }];
    30         
    31         return [RACDisposable disposableWithBlock:^{
    32             NSLog(@"connection disposableWithBlock ,thread = %@",[NSThread currentThread]);
    33         }];
    34     }];
    35      
    36      return signal;  
    37 }

    5.1 直接订阅 

    1 //    直接订阅
    2     
    3     RACSignal * signal = [self returnSignal];
    4     [signal subscribeNext:^(id  _Nullable x) {
    5 
    6         NSLog(@"subscribeNext x = %@ , thread = %@",x,[NSThread currentThread]);
    7 
    8     }];

    打印结果:

    5.2 Signal 抓化为:Connection

     1 //    将 signal 转化成 connection
     2     RACMulticastConnection * connection = [signal publish];
     3     
     4 //    订阅信号
     5     // RACSubject:RACSubscriber
     6     [connection.signal subscribeNext:^(id  _Nullable x) {
     7         
     8         NSLog(@"链接One x = %@ , thread = %@",x,[NSThread currentThread]);
     9     }];
    10     [connection.signal subscribeNext:^(id  _Nullable x) {
    11         
    12         NSLog(@"链接Two x = %@ , thread = %@",x,[NSThread currentThread]);
    13     }];
    14     
    15 //    连接
    16 //    RACSubject 订阅 RACSignal
    17     [connection connect];

    打印结果:

     6. RACCommand:处理事件的操作.(主线程中执行)

    (1) RACCommand : 内部必须返回 RACSignal

    (2) executionSignals : 信号外的信号

      (2.1) switchToLatest 最新发出来信号的 RACSignal 类型

      (2.2) 能过 (2.1)的诠释,那么只要用 switchToLatest subscribeNext: 订阅,就可以接收到发出来的信号

    (3) 下面是执行的顺序,用 (index)表示

    (4) execute:(id)input ; 该对象方法必须被调用(调用次数只有一次有效)才会执行一些相关操作,所有的 block 执行操作的 入口

     1     RACCommand * command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
     2         // input 即是执行 execute:(id)input; 传进来的值   (3)
     3         NSLog(@"init RACCommand block 被执行 initWithSignalBlock input = %@ , thread = %@",input,[NSThread currentThread]);
     4         
     5         return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
     6             // (6)
     7             NSLog(@"内部创建的信号block 被执行 createSignal , thread = %@",[NSThread currentThread]);
     8             
     9             // 发送信号
    10             [subscriber sendNext:@"create Signal for somthing %@"];
    11             [subscriber sendCompleted];
    12             
    13             return [RACDisposable disposableWithBlock:^{
    14                 // 当 [subscriber sendCompleted] 调用时就会执行释放功能的 block (8)
    15                 NSLog(@"内部信号被释放 disposableWithBlock , thread = %@",[NSThread currentThread]);
    16             }];
    17             
    18         }];
    19     }];
    20     
    21     // 订阅最新发出来信号的 signal (7)
    22     [command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
    23         
    24         NSLog(@"执行最近的 signal , x = %@ , thread = %@",x,[NSThread currentThread]);
    25     }];
    26     
    27     // executionSignals 这里传的 x 值类型为 RACDynamicSignal 类型对象 (5)
    28     [command.executionSignals subscribeNext:^(id  _Nullable x) {
    29         
    30         NSLog(@"executionSignals subscribeNext x = %@ , thread = %@",x,[NSThread currentThread]);
    31     }];
    32     
    33     // 查看将要执行,每执行完一个步聚 都会调用一次查看哪个 signal block(即 第 x 个 block  ) 将被使用 (2)(4)(9)
    34     // signal 的 skip: 方法功能是跳过 skipCount 个 使用 block 的查看
    35     [[[command executing] skip:0] subscribeNext:^(NSNumber * _Nullable x) {
    36         NSLog(@"executing signal subscribeNext x = %@ , thread = %@",x,[NSThread currentThread]);
    37     }];
    38     
    39     
    40     // 只执行一次 (1)
    41     [command execute:@"我要执行啦*****"];

    打印结果:


     7.NSObject 分类中 rac_liftSelector… 方法的使用(即等待成所有的 RACSignal 对象发送完信号再执行方法) (主程中执行)

     1     RACSignal * signalOne = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
     2         
     3         // 现在想发出信号了
     4         [subscriber sendNext:@"网络请求数据 1"];
     5         
     6         // 不需要释放操作
     7         return nil ;
     8     }];
     9     
    10     RACSignal * signalTwo = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    11         
    12         // 现在想发出信号了
    13         [subscriber sendNext:@"网络请求数据 2"];
    14         
    15         // 不需要释放操作
    16         return nil ;
    17     }];
    18     
    19     [self rac_liftSelector:@selector(updateUIWithSignalOneMessage:signalTwoMessage:) withSignalsFromArray:@[signalOne , signalTwo]];
    20 
    21 
    22 
    23 
    24 
    25 
    26 
    27 // 当所有数据都拿到手后更新UI , 传的数据就是 signalOne 和 signalTwo 发出来的信号数据 ,(所以当前设计的接收方法 也必需要有两个参数,发出的信号按顺序 传参)
    28 // 假如当前对象方法只设计 传一个参数,那么就会导致崩溃
    29 -(void)updateUIWithSignalOneMessage:(id)signalOneMessage signalTwoMessage:(id)signalTwoMessage
    30 {
    31     NSLog(@"signalOneMessage = %@ , signalTwoMessage = %@ , thread = %@",signalOneMessage,signalTwoMessage,[NSThread currentThread]);
    32 }

    打印结果:


    8. NSNotificationCenter : 使用了 RAC 把监听通知的方法改成了 block 形式

     1 // 监听通知
     2     [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidHideNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
     3         NSLog(@"NSNotification 1 x = %@",x.userInfo);
     4     }];
     5     
     6     [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidHideNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
     7         NSLog(@"NSNotification 2 x = %@",x.userInfo);
     8     }];
     9     
    10     // 发出通知
    11     [[NSNotificationCenter defaultCenter] postNotificationName:UIKeyboardDidHideNotification object:nil];
    12     

    打印结果:


    9. RAC UITextField 监听 text 变化

     1     // UITextField RAC使用
     2     UITextField * textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 100, 50)];
     3     textField.backgroundColor = [UIColor redColor];
     4     [self.view addSubview:textField];
     5     
     6     [[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
     7         NSLog(@"text = %@ , textField.text = %@ , thread = %@",x,textField.text,[NSThread currentThread]);
     8     }];
     9     
    10     
    11     // 绑定 lable.text
    12     UILabel * lable = [[UILabel alloc] initWithFrame:CGRectMake(100, 200, 100, 50)];
    13     lable.backgroundColor = [UIColor greenColor];
    14     [self.view addSubview:lable];
    15     
    16     // 绑定 lable.text 永远等于 textField.text
    17     RAC(lable,text) = textField.rac_textSignal ;

     输入为: China Welcome

    打印结果:


    10. RAC KVO 监听属性内容变化

     1     [RACObserve(self, age) subscribeNext:^(id  _Nullable x) {
     2         
     3         NSLog(@"KVO 监听到 age 内容发生变化 ,变为 %@ , thread = %@",x,[NSThread currentThread]);
     4     }];
     5 
     6 
     7 
     8 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
     9 {
    10     self.age++ ;
    11 }

    打印结果:


    11. RACSignal 的 bind 绑定

    bind 里面的做法:

        (1) 创建一个 RACSignal 对象做为 bind 方法的返值;

        (2) 当我们拿到该返的 RACSignal 类对象 tempSignal 去进行订阅;

        (3) 然后会执行创建 RACSignal 对象时的 block A (RACSignalBindBlock),并在里面执行 bindBlock 拿到 返回的 block B (RACSignal)(返回值为 RACSignal 对象);

        (4) 再执行 block B 就拿到 RACReturnSignal 对象;

        (5) RACReturnSignal 对象 进行订阅,然后在该订阅 block 里面拿到 value 值;

        (6) tempSignal 的 subscriber 订阅者 发送信号值 value , 最后在外面 tempSignal 对象的订阅就接收到信息了。

     1     UITextField * textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 300, 150)];
     2     textField.backgroundColor = [UIColor yellowColor];
     3     [self.view addSubview:textField];
     4     
     5     [[textField.rac_textSignal bind:^RACSignalBindBlock _Nonnull{
     6         
     7         NSLog(@"绑定 block");
     8         
     9         return ^RACSignal * (id _Nullable value, BOOL *stop){
    10             
    11             NSLog(@"返回block的值为 = %@",value);
    12             
    13             return [RACReturnSignal return:value];
    14         };
    15         
    16     }] subscribeNext:^(id  _Nullable x) {
    17         NSLog(@"signal subscribeNext x = %@",x);
    18     }];

    打印结果:


    12. RACReplaySubject 对象的 then: 方法

     then 功能:可以使 RACSignal 及其子类的 对象有序接收信号

     1     // 在这里尽量使用 RACReplaySubject 类 ,因为 RACReplaySubject 可以先发送信号,订阅代码可以放在之后写。
     2     // 如果 使用 RACSignal 或 RACSubject ,那么必须要等这些对象订阅完后,发送的信号才能接收的到
     3     RACReplaySubject * subjectA = [RACReplaySubject subject];
     4     
     5     // 这就是好处,先发送
     6     [subjectA sendNext:@"AA"];
     7     // 必须要调用这个方法才会来到 then 后的 block
     8     [subjectA sendCompleted];
     9     
    10     // 按指定的顺序接收到信号
    11     [[[subjectA then:^RACSignal * _Nonnull{
    12         
    13         // 当 subjectA 发送信号完成后 才执行 当前的 block
    14         RACReplaySubject * subjectB = [RACReplaySubject subject];
    15         
    16         // 可以单独调用发送信号完成的方法就可以接着执行下一个 then
    17         [subjectB sendCompleted];
    18         
    19         return subjectB ;
    20         
    21     }] then:^RACSignal * _Nonnull{
    22         
    23         // 当 subjectB 发送信号完成后 才执行 当前的 block
    24         RACReplaySubject * subjectC = [RACReplaySubject subject];
    25         
    26         // subjectC 发送信号
    27         [subjectC sendNext:@"CC"];
    28         
    29         return subjectC ;
    30         
    31     }] subscribeNext:^(id  _Nullable x) { // 这个就 "相当于" 订阅了 subjectC 对象(但真正的对象则不是 subjectC 对象) ,x = @"CC"
    32         NSLog(@"RACReplaySubject C x = %@",x);
    33     }];

    打印结果:


    13. 合并两个及以上 RACSignal 或 RACSignal 的子类对象,用新创建的 RACSignal 对象接收多个 RACSignal 或 RACSignal 的子类对象 发出的信号

     1 RACReplaySubject * subjectA = [RACReplaySubject subject];
     2     RACReplaySubject * subjectB = [RACReplaySubject subject];
     3     RACReplaySubject * subjectC = [RACReplaySubject subject];
     4     
     5     // 三个对象发送信号(只需其中一个或多个发送信号时,合并的 信号对象 都可以在订阅的 block 接收到信息)
     6     [subjectB sendNext:@"BB"];
     7     [subjectA sendNext:@"AA"];
     8     [subjectC sendNext:@"CC"];
     9     
    10     // 合并两个信号对象变成一个接收信号对象 subjectD , subjectD 订阅 接收 subjectB 和 subjectA 发送的信号
    11     [[[subjectA merge:subjectB] merge:subjectC] subscribeNext:^(id  _Nullable x) {
    12         NSLog(@"%@",x);
    13     }]; 

    打印结果:

     


    14. 压缩两个及以上 RACSignal 或 RACSignal 的子类对象,用新创建的 RACSignal 对象同时接收多个 RACSignal 或 RACSignal 的子类对象 发出的信号

     1     RACReplaySubject * subjectA = [RACReplaySubject subject];
     2     RACReplaySubject * subjectB = [RACReplaySubject subject];
     3     RACReplaySubject * subjectC = [RACReplaySubject subject];
     4     
     5     // 三个对象同时发送信号,缺一不可
     6     [subjectA sendNext:@"信号AA"];
     7     [subjectB sendNext:@"信号BB"];
     8     [subjectC sendNext:@"信号CC"];
     9     
    10     // 合并两个信号对象变成一个接收信号对象 subjectD , subjectD 订阅 接收 subjectB 和 subjectA 发送的信号
    11     // x 类型为 元组 RACTwoTuple 类型:解析使用
    12     [[[subjectA zipWith:subjectB] zipWith:subjectC] subscribeNext:^(id  _Nullable x) {
    13         // 注意:元组需要 一层一层 地解析
    14         RACTupleUnpack(RACTuple * AB , NSString * C) = x ;
    15         NSLog(@"x的值为:%@",x);
    16 
    17         RACTupleUnpack(NSString * A , NSString * B) = AB ;
    18         NSLog(@"AB的值为:%@",AB);
    19         
    20         NSLog(@"A = %@ , B = %@ , C = %@",A , B , C);
    21     }];

     打印结果:


    15. 合并两个及以上 RACSignal 或 RACSignal 的子类对象,用新创建的 RACSignal 对象 同时接收多个 RACSignal 或 RACSignal 的子类对象 发出的信号

    公共的代码: 

    1 RACReplaySubject * subjectA = [RACReplaySubject subject];
    2     RACReplaySubject * subjectB = [RACReplaySubject subject];
    3     RACReplaySubject * subjectC = [RACReplaySubject subject];
    4     
    5     // 三个对象同时发送信号,缺一不可
    6     [subjectA sendNext:@"邮件AA"];
    7     [subjectB sendNext:@"邮件BB"];
    8     [subjectC sendNext:@"邮件CC"];

    方法一:

     1     //也可以把那些信号传的参数聚合成一个值
     2     //   遵守 NSFastEnumeration 协议的类都可成为数组
     3     //   reduce block 参数可以自己根据信号设置
     4     [[RACSignal combineLatest:@[subjectA,subjectB,subjectC] reduce:^id (NSString * signalA,NSString * signalB,NSString * signalC){
     5         
     6         // 把这 三个中任意 一个发出的信号值 聚合成一个值 NSString 类型
     7         
     8         return [NSString stringWithFormat:@"A = %@ , B = %@ , C = %@",signalA , signalB , signalC];
     9         
    10     }] subscribeNext:^(id  _Nullable x) {
    11         NSLog(@"聚合后三个值变成一个 NSString 类型的值: %@",x);
    12     }];

    打印结果:

    方法二:

     1 //    也可以用聚合绑定做法
     2     UILabel * lable = [[UILabel alloc] initWithFrame:CGRectMake(30, 60, 380, 100)];
     3     [self.view addSubview:lable];
     4     lable.backgroundColor = [UIColor redColor];
     5     RAC(lable , text) = [RACSignal combineLatest:@[subjectA,subjectB,subjectC] reduce:^id (NSString * signalA,NSString * signalB,NSString * signalC){
     6         
     7         // 把这 三个中任意 一个发出的信号值 聚合成一个值 NSString 类型
     8         
     9         return [NSString stringWithFormat:@"A = %@ , B = %@ , C = %@",signalA , signalB , signalC];
    10         
    11     }];
    12     
    13     NSLog(@"lable.text = %@",lable.text);

    打印结果:


    16. RACSignal 的 map 拦截信号发出的信号和处理数据

    1     RACReplaySubject * signal = [RACReplaySubject subject];
    2     
    3     [[signal map:^id _Nullable(id  _Nullable value) {
    4         return [NSString stringWithFormat:@"%@ (拦截发出的信号,拼接个想要的东西)",value];
    5     }] subscribeNext:^(id  _Nullable x) {
    6         NSLog(@"接收到处理后的信息 = %@",x);
    7     }];
    8     
    9     [signal sendNext:@"@(当前信号的信息是Welcome Orange World)"];

    结果:


    17. 信号中的信号,RACSignal 的 flattenMap 对象方法,用来接收信号对象value 和 信号对象value发出的信息

     1 RACReplaySubject * signal = [RACReplaySubject subject];
     2     RACSubject * subject = [RACSubject subject];
     3     
     4     [[signal flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
     5         
     6         // value 是信号对象 == subject
     7         
     8         return [value map:^id _Nullable(id  _Nullable value) {
     9             
    10             return [NSString stringWithFormat:@"(添加拦截信号处理信号) (%@)",value];
    11         }];
    12     }] subscribeNext:^(id  _Nullable x) {
    13         NSLog(@"接收到处理后的信息 = %@",x);
    14     }];
    15     
    16     [signal sendNext:subject];
    17     
    18     [subject sendNext:@" subject 发出信号了"];

    结果:


    18. 信号过滤器:RACSignal 的 filter: 方法,用来设置一个条件发出的信号才会被接收到

     1 RACReplaySubject * replaySubject = [RACReplaySubject replaySubjectWithCapacity:1];
     2     
     3     // filter block 是一个过滤器,只有满足条件发出的信号才会被接收到
     4     [[replaySubject filter:^BOOL(id  _Nullable value) {
     5         
     6         return ((NSString *)value).length >= 6 ;
     7         
     8     }] subscribeNext:^(id  _Nullable x) {
     9         
    10         NSLog(@"接收到信号 = %@",x);
    11     }];
    12     
    13     //        // 发出的信号长度为 5 时,订阅收不到信号信息
    14     //        [replaySubject sendNext:@"12345"];
    15     
    16     // 发出的信号长度为 >= 6 时,订阅收到信号了信息
    17     [replaySubject sendNext:@"123456"];

    结果:


     

    19.RACSignal 信号对象 与 定时器的关系

    公用变量:

     1 // 定时器
     2     // TimeInterval : 间隔时间,秒
     3     // repeats      : 是否重复
     4     // blokc        : 调用代码块 (在主线程中执行)
     5     if (@available(iOS 10.0, *)) {
     6         [NSTimer scheduledTimerWithTimeInterval:1 repeats:NO block:^(NSTimer * _Nonnull timer) {
     7             NSLog(@"每隔一秒调用一次当前 block , thread = %@",[NSThread currentThread]);
     8         }];
     9     } else {
    10     }

    方法一:

     1 // RACSignal 制定定时器
     2     // interval : 间隔的时间,秒
     3     /**
     4      onScheduler : 多线程 , 队列
     5      mainThreadScheduler : 主线程中 执行订阅代码块
     6      currentScheduler    : 在当前创建时的线程中 执行订阅代码块
     7      */
     8     /**
     9      schedulerWithPriority: 或 schedulerWithPriority:name: 优先级 , name 表示线程名
    10      // 优先级高,开起 新的线程
    11      RACSchedulerPriorityHigh        = DISPATCH_QUEUE_PRIORITY_HIGH,
    12      // 默认优先级,开起 新的线程
    13      RACSchedulerPriorityDefault     = DISPATCH_QUEUE_PRIORITY_DEFAULT,
    14      // 优先级低,开起 新的线程
    15      RACSchedulerPriorityLow         = DISPATCH_QUEUE_PRIORITY_LOW,
    16      // app 进入后台也可以调用,开起 新的线程
    17      RACSchedulerPriorityBackground  = DISPATCH_QUEUE_PRIORITY_BACKGROUND,
    18      */
    19     
    20     [[RACReplaySubject interval:1 onScheduler:[RACScheduler schedulerWithPriority:RACSchedulerPriorityLow]] subscribeNext:^(NSDate * _Nullable x) {
    21         // x 是当前的时间
    22         NSLog(@"每隔一秒调用订阅代码:x = %@ , 在线程 thread = %@",x,[NSThread currentThread]);
    23     }];

    打印结果:

    方法二:

     1     [NSTimer scheduledTimerWithTimeInterval:1 repeats:NO block:^(NSTimer * _Nonnull timer) {
     2         NSLog(@"每隔一秒调用一次当前 block , thread = %@",[NSThread currentThread]);
     3     }];
     4     
     5     [[[RACReplaySubject createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
     6         
     7         [subscriber sendNext:@"~~2秒后调用订阅 block"];
     8         
     9         return nil ;
    10     }] delay:2] // 延时 5秒 再
    11      subscribeNext:^(id  _Nullable x) {
    12          
    13          NSLog(@"-------------%@",x);
    14      }];

    结果:

     

  • 相关阅读:
    基础数据补充
    购物车
    小数据池、深浅拷贝和集合
    列表、元组和range
    小数据池、深浅拷贝和集合练习
    字典
    字符串练习
    列表练习
    练习
    字典练习
  • 原文地址:https://www.cnblogs.com/EchoHG/p/8353836.html
Copyright © 2011-2022 走看看