iOS Developer程序员@IT·互联网

RACSignal 浅析

2017-04-18  本文已影响30人  漂泊海上的大土豆

RACSignalRAC 中的核心并不过分,这个框架的本质就是信号的产生,分发与订阅。


“A signal, represented by the RACSignal class, is a push-driven
stream.”

官方文档介绍中有说 signalpush-driven 的,但信号在没有订阅者的时候是 cold 状态,只有被订阅后才变成 hot 并开始分发。也就是常说的冷信号与热信号。
大神 sunnyxx 把这种现象生动的比喻成巧克力工厂,生产一个吃一个。有订单才生产,没有订单就不开工。

// 创建一个基本 signal
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendNext:@2];
        [subscriber sendCompleted];
        return nil;
    }];

这样没人订阅什么也不会发生,block 里面的代码并没有执行。

    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@", x);
    }];

有人订阅(有了订单)后信号被激活,发一个就收到一个(生产一个吃一个巧克力)。

2017-04-18 11:46:04.717 simpleRacDemo[15054:2153646] 1
2017-04-18 11:46:04.717 simpleRacDemo[15054:2153646] 2
2017-04-18 11:46:04.717 simpleRacDemo[15054:2153646] dispose

一共生产了两块巧克力🍫。


最基本的 next、completed,error

[signal subscribeNext:^(id x) {// 信号产生的值
    NSLog(@"x = %@", x);
} error:^(NSError *error) {// 错误返回
    NSLog(@"error = %@", error);
} completed:^{// 信号成功结束,不带值
    NSLog(@"completed");
}];

当信号成功结束后会 dispose 表明自己已经被了结。


map 映射

map 这个概念在很多语言都有,在 RAC 中会把 signal 发送来的值逐个过滤一次,输出新的目标序列。

    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendNext:@2];
        [subscriber sendCompleted];
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"dispose");
        }];
    }];
    
    [[signal map:^id _Nullable(id  _Nullable value) {
        return [value isEqual:@1] ? @1 : @"not equal";
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
2017-04-18 15:05:27.185 simpleRacDemo[15463:2436314] 1
2017-04-18 15:05:27.186 simpleRacDemo[15463:2436314] not equal
2017-04-18 15:05:27.186 simpleRacDemo[15463:2436314] dispose

当收到 @2 时经过我们三目运算的处理打印了 not equal


filter 过滤

这个看名字就会了解是过滤掉不符合条件的返回值
稍微改一下上面的订阅

    [[signal filter:^BOOL(id  _Nullable value) {
        return [value isEqual:@1];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
2017-04-18 15:10:57.899 simpleRacDemo[15515:2461820] 1
2017-04-18 15:10:57.900 simpleRacDemo[15515:2461820] dispose

只有 1 满足条件


以上是十分常用的方法,RAC 中的其它方法还有很多。可以根据相应的业务场景深入研究。

take — takeLast/takeUntil/takeWhileBlock

最基本的使用就是拿,后面参数是 NSInteger ,代表了拿前这么多个值。

skip — skipWhileBlock/skipUntilBlock

相对应的跳过前 n 个值。

repeat/repeatWhileBlock

重复发送信号

delay

延迟发送


throttle 节流

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

文本输入变化很多,限制0.5秒无变化才响应。


distinctUntilChanged

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

相应的不发送两次相同的请求,有变化才响应。


timeout 超时


ignore

还是把上面的订阅修改一下,忽视 @1。

    [[signal ignore:@1] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
2017-04-18 15:44:51.597 simpleRacDemo[15975:2565685] 2
2017-04-18 15:44:51.597 simpleRacDemo[15975:2565685] dispose

如同期望只剩下了 @2。


小结


参考资料:

上一篇 下一篇

猜你喜欢

热点阅读