记录一下RAC的使用

1  常规的对数组的操作,包括遍历、刷选、映射、替换

 // 遍历
NSArray * array = @[@"1",@"2",@"3",@"4",@"5",@"6"]; [array.rac_sequence.signal subscribeNext:^(id _Nullable x) { NSLog(@"数组内容:%@", x); }];

注释:可遍历所有元素,但因为内部实现是异步执行的(for in是在当前线程),所以使用时候需要注意时间顺序。 // 刷选 NSArray
*filter = [[array.rac_sequence filter:^BOOL(id value) { return [value integerValue] > 2; }] array]; NSLog(@"filter:%@",filter); // (3,4,5,6) // 映射 NSArray *map = [[array.rac_sequence map:^id(id value) { NSInteger a = [value integerValue] * [value integerValue]; return [NSString stringWithFormat:@"%ld", a]; }] array]; NSLog(@"map:%@",map); //(1,4,9,16,25,36)


   // 数组替换所有元素

    NSArray * array1 = @[@"1",@"2",@"3",@"4",@"5",@"6"];

    NSArray * newArray = [[array1.rac_sequence mapReplace:@"99"] array];

    NSLog(@"%@",newArray);

 

 

2 节流  throttle   

 表示 指定时间间隔内,不再发送信号  这里添加 throttle, 表示在 1 秒内 text 没有改变时,才会进行搜索请求

 UITextField *textfield;
    [[[textfield rac_textSignal]
      throttle:1]
     subscribeNext:^(id x) {
         NSLog(@"开始搜索请求==%@", x);
     }];

 

3  事件处理    KVO监听   通知等

 UITextField * textF;
    //实时监听输入框中文字的变化
    [[textF rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"输入框的内容--%@",x);
    }];
    
    //UITextField的UIControlEventEditingChanged事件,免去了KVO
    [[textF rac_signalForControlEvents:UIControlEventEditingChanged] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@",x);
    }];
    //添加监听条件
    [[textF.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return [value isEqualToString:@"100"];//此处为判断条件,当输入的字符为100的时候执行下面方法
    }]subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"输入框的内容为%@",x);
    }];
    
    UIButton *loginBtn;
    //监听点击事件
    [[loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@",x);//x为一个button对象,别看类型为UIControl,继承关系UIButton-->UIControl-->UIView-->UIResponder-->NSObject
        x.frame = CGRectMake(100, 210, 200, 300);
    }];
    //KVO监听按钮frame的改变
    [[loginBtn rac_valuesAndChangesForKeyPath:@"frame" options:(NSKeyValueObservingOptionNew) observer:self] subscribeNext:^(RACTwoTuple<id,NSDictionary *> * _Nullable x) {
        NSLog(@"frame改变了%@",x);
    }];
    
    //定时器
    [[RACSignal interval:2.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        NSLog(@"你好哇。");
        //这里面的方法2秒一循环
    }];
    
    //通知。。。不需要注销了
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@ 键盘弹起", x); // x 是通知对象
    }];

 

 

4 反向传值,也可以使用block  代理  通知,但是使用RAC最简单

在controller中

 SubView *subView = [[SubView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    subView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:subView];
    
    [[subView rac_signalForSelector:@selector(sendValues:data:)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@"===111%@",x);
    }];

在SubView.h中声明这个方法

- (void)sendValues:(NSString *)type data:(NSDictionary *)dicc;

在SubView.m中调用这个方法

- (void)btnAction:(UIButton *)sender
{
    [self sendValues:@"111" data:@{@"key" : @"values"}];
}

 

 

5  RACSubject使用

// 创建信号
    RACSubject *subject = [[RACSubject alloc] init];
    
    // 订阅信号
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"==%@",x);
    }];
    // 发送信号
    [subject sendNext:@"今天天气还是一如既往的好,希望明天也是如此"];

 

6  关于多请求的处理,其实可以使用GCD等方式,但是这里使用RAC还是比较方便的

    

- (void)demo7
{
    RACSignal *single1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        // 1:请求数据
        // 2:发送数据
        [subscriber sendNext:@"single1"];
        return nil;
    }];
   
    RACSignal *single2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        // 1:请求数据
        // 2:发送数据
        [subscriber sendNext:@"single2"];
        return nil;
    }];
    
    // 订阅信号
    [single1 subscribeNext:^(id  _Nullable x) {
        NSLog(@"------处理1..%@",x);
    }];
    
    [single2 subscribeNext:^(id  _Nullable x) {
        NSLog(@"------处理2。。%@",x);
    }];
    
    // 当数组中所有信号都发送了数据,才会执行selector,必须带参,参数是sendNext发送过来的,必须和信号一一对应
    // 参数:每个信号发送的数据,这里必须要带参数,不然会崩溃
    [self rac_liftSelector:@selector(updateUIOneData:TwoData:) withSignalsFromArray:@[single1,single2]];
}

- (void)updateUIOneData:(id)x1 TwoData:(id)x2
{
    NSLog(@"更新UI:%@----%@",x1,x2);
}

 

 

7. 使用宏

 UILabel *myLabel;
    // 监测某个对象的属性,发生变化时回直接回调给block
    [RACObserve(myLabel, text) subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    // RAC:把一个对象的某个属性绑定一个信号,只要发出信号,就会把信号的内容给对象的属性赋值
    // 给label的text属性绑定了文本框改变的信号
    UITextField *textfield;
    RAC(myLabel, text) = textfield.rac_textSignal;
    [textfield.rac_textSignal subscribeNext:^(id x) {
        myLabel.text = x;
    }];

举一个监听的例子。

需求就是监听scrollerview 的滑动。当滑动的时候就输出日志。如下:

UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
scrolView.contentSize = CGSizeMake(200, 800);
scrolView.backgroundColor = [UIColor greenColor];
[self.view addSubview:scrolView];
[RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
    NSLog(@"success");
}];

 

8. 补一下merge 和 combineLatest 的用法。

先看代码吧:

 RACSubject *aaaaa = [RACSubject subject];
    RACSubject *bbbbb = [RACSubject subject];
    [[RACSignal merge:@[aaaaa,bbbbb]]subscribeNext:^(id x) {
         NSLog(@"信号发送combineLatest:%@",x);
    }];
    
    
    [aaaaa sendNext:@"1000"];
    [bbbbb sendNext:@"2000"];

和  

 RACSubject *aaaaa = [RACSubject subject];
    RACSubject *bbbbb = [RACSubject subject];
    [[RACSignal combineLatest:@[aaaaa,bbbbb]]subscribeNext:^(id x) {
         NSLog(@"信号发送combineLatest:%@",x);
    }];
    
    
    [aaaaa sendNext:@"1000"];
    [bbbbb sendNext:@"2000"];

这两个非常相似,merge指的是只要发送一个信号,block就会回掉,然后回调回来的是那个改变你的singal的值

而combineLatest也是只要发送一个信号,block就会回调,然后把所有信号的值以元祖的形式返回来

 

 

 

 

参考文章: https://www.jianshu.com/p/666bc733559a

posted @ 2019-06-28 14:12  走路蹩脚的火星人  阅读(912)  评论(0编辑  收藏  举报