RAC信号处理

作者: TyroneLin | 来源:发表于2018-04-24 17:00 被阅读0次

    map -- 映射

    创建一个订阅者的映射并且返回数据(例:将textField的字符串转为其本身长度)

    [[self.textField.rac_textSignal map:^id(NSString *value) {
        NSLog(@"%@", value);
        return value.length;
    }] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    

    flattenmap -- 扁平映射(信号中的信号)

    实际上是根据前一个信号传递进来的参数重新建立了一个信号,这个参数,可能会在创建信号的时候用到,也有可能根本用不到

    - (RACSignal *)signInSignal {
        return [RACSignal createSignal:^RACDisposable *(id subscriber){
            [self.signInService
             signInWithUsername:self.usernameTextField.text
             password:self.passwordTextField.text
             complete:^(BOOL success){
                 [subscriber sendNext:@(success)];
                 [subscriber sendCompleted];
             }];
            return nil;
        }];
    }
    
    
        [[[self.signInButton
           rac_signalForControlEvents:UIControlEventTouchUpInside]
          map:^id(id x){
              return [self signInSignal];
          }]
         subscribeNext:^(id x){
             NSLog(@"Sign in result: %@", x);
         }];
    

    此时当我们使用map映射的是一个信号(即信号中的信号),映射出来的value是(RACSignal *),这时我们subscribeNext的value即为此信号类型,而不是信号中的value值;所以这里调用flattenMap,创建新的信号,使用(RACSignal *)的value作为新信号的value,也就是我们需要的值。

    补充

    map 与 swtichToLatest结合类似于flattenMap
    switchToLatest:选择最新的信号的value,比如我依次发送3个signal,但是switchToLatest只取第三个响应信号的value。

    filter -- 过滤

    信号变化时筛选出需要的信号(例:当textField的字符串长度大于3时,信号才会响应)

    [[self.textField.rac_textSignal filter:^BOOL(NSString *value) {
        return value.length > 3;
    }] subscribeNext:^(id x) {
        NSLog(@"x = %@", x);
    }];
    

    take/skip/repeat -- 获取/跳过/重复

    RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"1"];
        [subscriber sendNext:@"2"];
        [subscriber sendNext:@"3"];
        [subscriber sendNext:@"4"];
        [subscriber sendNext:@"5"];
        [subscriber sendCompleted];
        return nil;
    }] take:2];
    
    [signal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }completed:^{
        NSLog(@"completed");
    }];
    

    这个signal只会输出前两个信号1和2还有完成信号completed,skip repeat同理。
    相似的还有takeLast takeUntil takeWhileBlock skipWhileBlock skipUntilBlock repeatWhileBlock都可以根据字面意思来理解。

    distinctUntilChanged

    网络请求中为了减轻服务器压力,无用的请求我们应该尽可能不发送。distinctUntilChanged的作用是使RAC不会连续发送两次相同的信号,这样就解决了这个问题。

    [[[self.textField rac_textSignal] distinctUntilChanged] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    

    ignore -- 忽略

    指定一个任意类型的量(可以是字符串,数组等),当需要发送信号时讲进行判断,若相同则该信号会被忽略发送。

    [[[self.textFild rac_textSignal] ignore:@"good"] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    

    delay -- 延时

        RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"delay"];
            [subscriber sendCompleted];
            return nil;
        }] delay:2];
        
        NSLog(@"tag");
        
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    

    throttle --节流

    在我们做搜索框的时候,有时候需求的时实时搜索,即用户每每输入字符,view都要求展现搜索结果。这时如果用户搜索的字符串较长,那么由于网络请求的延时可能造成UI显示错误,并且多次不必要的请求还会加大服务器的压力,这显然是不合理的,此时我们就需要用到节流。

    [[[self.textFild rac_textSignal] throttle:0.5] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    

    加了节流管道,后面跟上了类型为NSTimeInterval的参数后,只有0.5S内信号不产生变化才会发送请求,这样快速的输入也不会造成多次输出。

    timeout -- 超时信号

    当超出限定时间后会给订阅者发送error信号。

    RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
                [subscriber sendNext:@"delay"];
                [subscriber sendCompleted];
            }];
            return nil;
        }] timeout:2 onScheduler:[RACScheduler mainThreadScheduler]];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        } error:^(NSError *error) {
            NSLog(@"%@", error);
        }];
    

    由于在创建信号是限定了延迟3秒发送,但是加了timeout2秒的限定,所以这一定是一个超时信号。这个信号被订阅后,由于超时,不会执行订阅成功的输出x方法,而是跳到error的块输出了错误信息。timeout在用RAC封装网络请求时可以节省不少的代码量。

    参考自 【cbsfly的博客】

    相关文章

      网友评论

        本文标题:RAC信号处理

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