ReactiveCocoa总结

前端之家收集整理的这篇文章主要介绍了ReactiveCocoa总结前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

五月份的时候研究过一段时间RAC,后来因为换了新工作,公司的事情挺多,这段时间公司的事情少点了,又从新拾起了RAC的学习,已经看了很多的别人的博客,里面的东西也都是从别人的博客偷得,现在把我总结的一些东西,写出来.
开始!

.
0. 监听协议方法被触发

[[self rac_signalForSelector:@selector(tableView:didSelectRowAtIndexPath:) fromProtocol:@protocol(UITableViewDelegate)] subscribeNext:^(id x) {
        }];
  1. RAC广播
    特别喜欢这个功能,当初之所以学习RAC就是因为看到了广播可以这没写,再也不用想那么方法了,直接使用block. 很方便
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"test" object:nil] subscribeNext:^(id x) {
    }];

3.concat 信号连接

RACSignal *signalA;
     RACSignal *signalB;
     [signalA concat:signalB] subscribeNext:^(id x){
     NSLog(@“%@“,x);
     }

signalA相当于皇帝,signalB相当于太子,只要皇帝没有sendcompleted,太子就不能发号命令
4.merge 信号合并,合并多个信号,只要任何一个信号有了输出,结合体就有输出

RACSignal *signalA;
     RACSignal *signalB;
     [signalA merge:signalB] subscribeNext:^(id x){
     NSLog(@“%@“,x);
     }

A或者B有了新信号都会输出
5. combineLatest 信号组合

[[signalA combineLatest:signalB]  subscribeNext:^(RACTuple* x){
         RACTupleUnpack(NSSTring *stringA,NSString *stringB) = x;
         NSLog(@“%@ %@“,stirngA,stringB);
     }
        RACSignal *signalA;  输出 A_1 A_2
     RACSignal *signalB;  输出 B_1
                          最终结果 A_2 B_1

合并体输出的值是各个信号的最新输出
6. zipWith 压缩(不知道有没有更好的翻译)

RACSignal *signalA;  输出 A_1 A_2
     RACSignal *signalB;  输出 B_1 B_2
                          最终输出: A_1 B_1   A_2 B_2
     [signalA zipWith:signalB subscribeNext:^(RACTuple* x){
         RACTupleUnpack(NSSTring *stringA,stringB);
     }
当A和B都有了新值的时候才输出,输出的是一个结合体  RACTuple 需要只用TupleUnPack进行分解,有个把这个方法比作成了夫妻,夫妻两个共同输入密码才能打开密码箱,其中一个人completed,夫妻就解散了.

7. map 映射(转换,转型 (大概意思吧))

[signal map:^id(id value){
               if([value isEqualToString:@“石”]){
                     Return @“金”;
          }]

点石成金,好方法
8. filter 过滤

[signal filter:^BOOL(id value){
     return [value intvalue]>3;
   }]

符合条件的才允许通过
9. flattenMap 过滤 返回的是一个信号 但是没有发现好的解释,以后更新
10. then then方法会等completed事件发出后调用(具体有什么实际用处暂未发现)

[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"test- then"];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
            [subscriber sendCompleted];
        });
        return nil;
    }]
     then:^RACSignal *{
         NSLog(@"then-Action");
         return nil;
     }]
     subscribeNext:^(id x) {
        NSLog(@"x:%@",x);
    }];

过了五秒,会输出 then-Action
11. delay 延迟输出

[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@"hello world"];
        return nil;
    }] delay:5]
    subscribeNext:^(id x) {
        NSLog(@"x:%@",x);
    }];

.
12. replay 重放

__block int aNumber = 0;
              RACSignal *asignal = [[RACSignal createSignal:^RACDisposable *
                              (id<RACSubscriber> subscriber) {
                                 aNumber++;
                            [subscriber sendNext:@(aNumber)];
                            [subscriber sendCompleted];
                            return nil;
                        }] replay];
              [asignal subscribeNext:^(id x) {
                  NSLog(@"x:%@",x);
              }];
              [asignal subscribeNext:^(id x) {
                  NSLog(@"x:%@",x);
              }];
              输入 1 1
              如果不加replay  输出1  2

可以防止side effect(副作用,不知道有没有更好的方法) 保证signal只被触发一次,然后把sendNext的value存起来,下次再subscribe时,直接发送缓存数据
13. intervel 定时

[RACSignal intervel:1.0f onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x){ NSLog(@“你该吃药"); }

每隔一秒输出一次
14. retry 重试

__block int index = 0;
             [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                 if (index <10) {
                     index ++;
                NSLog(@"失败");
                [subscriber sendError:nil];
                 }
              else{
                NSLog(@"我成功了");
                [subscriber sendNext:nil];
                 }
                 return nil;
             }] retry] subscribeNext:^(id x) {
                  NSLog(@"终于成功");
               }];

一直尝试,直到输出不是error
15. throttle:time 节流 在一定的时长,只能通过一个信号,如果在这个时间内有其他的操作,需要等待time时长

__block int index = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) { index++; [subscriber sendNext:[NSString stringWithFormat:@"%d",index]];
        }];
        return nil;
    }]throttle:1]
    subscribeNext:^(id x) {
        NSLog(@"x:%@",x);
    }];

在一秒内只能输出一个信号,我设置的每隔两秒输出一次,如果把throttle:时间比定时的时间长,永远也不会subscribeNext
16. takeUntil:signalA 直到接收到这个信号,才停止subscribeNext

[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [[RACSignal  interval:1.0f onScheduler:[RACScheduler mainThreadScheduler]]
         subscribeNext:^(id x) {
             [subscriber sendNext:@"直到世界尽头才能把我们分开"];
         }];
        return nil;
    }] takeUntil:[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,^{
            NSLog(@"世界尽头到了");
            [subscriber sendNext:@"世界尽头到了"];
        });
        return nil;
    }]] subscribeNext:^(id x) {
        NSLog(@"x:%@",x);
    }];

传言这个takeUntil用的好的地方还是cell中btn 的复用,防止btn每次复用时,btn都会被addTarget:selector;

[[[cell.detailBtn race_signalForcontrolEvents:UIControlEventTouchUpInside] takeUntil:celeriac_prepareForReuseSignal]
          subscribeNext:^(id x){ }];

17 UIView CateGories 文档里面有各种view,这里讲一下,我最喜欢用的一个view

UIAlertView *alter = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"alter" delegate:nil cancelButtonTitle:@"确定"otherButtonTitles:@"取消",nil];
               [alter show];
              [[alter rac_buttonClickedSignal] subscribeNext:^(id x) { NSLog(@"subscribeNext:%@",x);
                }];

太棒了,真心喜欢这么用,
18. NSObject CateGories
18.1 rac_willDealllocSignal 对象即将被摧毁的时候调用

NSArray *array = @[@“foo"]; [array rac_willDealllocSignal] subscribeCompleted:^{ nslog(@“oops");
          }];
          array = nil;

不知道这段代码没有执行,正在寻找问题
18.2 rac_liftSelector:@select(methods)withSignals:signalA,signalB 绑定两个信号,只要两个信号都有输出值,才会触发methods方法,接下来只有任何一个signal有了新的值,都会自动触发

[subscriber sendNext:@"C"];
        double delayInSeconds = 2.0;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(delayInSeconds * NSEC_PER_SEC)),^{
            [subscriber sendNext:@"A"];

        });
        return nil;
    }];
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"B"];
// [subscriber sendNext:@"C"];
        return nil;
    }];
- (void)doA:(NSString *)A withB:(NSString*)B{
    NSLog(@"A:%@ B:%@",A,B);
}

输出
A:C B:B
A:A B:B

  1. 只要有RACObserve的地方都有使用 weakify/strongify 消除循环引用
  2. ignore:(id) 忽略给定的值
[[self.inputTextField.rac_textSignal ignore:@"su"] subscribeNext:^(NSString *value) {
    NSLog(@"`sunny` could never appear : %@",value);
}];

暂时还没有发现怎么好用,比如上面 我过滤的是 su 输入s 输出s 输入 u 不输出,输入s 输出sus
21. ignoreValues 忽略所有值,只关心signal结束,只取complete和error两个消息
22. distinctUntilChanged 将这次的值和上次的值作比较,如果相同则忽略

__block int index = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]]subscribeNext:^(id x) { [subscriber sendNext:[NSString stringWithFormat:@"%d",index]];
        }];
        return nil;
    }] distinctUntilChanged] subscribeNext:^(id x) {
        NSLog(@"x:%@",x);
    }];

只会输出0
23. take: 从开始取N次的next的值,不包括completion和error

__block int index = 0;
    [[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] take:5] subscribeNext:^(id x) {
        index ++;
        NSLog(@"index:%d",index);
    }];

输出: 1 2 3 4 5
24,takeLast: 取最后的N次next的值,等待error 或者completion之后输出.

__block int index = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) { index++; [subscriber sendNext:[NSString stringWithFormat:@"%d",index]];
        }];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,^{
            [subscriber sendCompleted];
        });
        return nil;
    }]
     takeLast:3]
     subscribeNext:^(id x) {
        NSLog(@"x:%@",x);
    }];

输出 3 4 5

25,takeUntil: signal 在接受到某个信号之前,一直取值,直到接收到这个信号,不再取值

__block int index = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) { index++; [subscriber sendNext:[NSString stringWithFormat:@"%d",index]];
        }];
        return nil;
    }]
      takeUntil:[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,^{
            [subscriber sendCompleted];
        });
        return nil;
    }]]
     subscribeNext:^(id x) {
         NSLog(@"x:%@",x);
     }];

输出 1,2,3,4
26 skip:N 从开始跳过N次的next值

__block int index = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) { index++; [subscriber sendNext:[NSString stringWithFormat:@"%d",index]];
        }];
        return nil;
    }]
     skip:3]
     subscribeNext:^(id x) {
         NSLog(@"x:%@",x);
     }];

输出: 4 5 6 ……
27 skipUntilBlock 一直跳等到block输出为yes,才有输出

__block int index = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) { index++; [subscriber sendNext:[NSString stringWithFormat:@"%d",index]];
        }];
        return nil;
    }]
     skipUntilBlock:^BOOL(id x) {
         NSString *str = [NSString stringWithFormat:@"%@",x];
         return [str intValue]>3;
     }]
     subscribeNext:^(id x) {
         NSLog(@"x:%@",x);
     }];

输出 4 5 6….. 28 skipWhileBlock 和skipUntilBlock 的区别 感觉像是 while do 和 do while的区别

猜你在找的React相关文章