Winter's House.

ReactiveCocoa-RACSignal

字数统计: 783阅读时长: 3 min
2019/03/31 Share

RACSignal使用基础

ReactiveCocoa的基础—-信号。信号变相来说也是一种对象,需要创建,本身不具备发送的能力

获取信号的方式

单元信号

1
2
3
4
5
RACSignal *signal1 = [RACSignal return:@"some value"];
NSError *error;
RACSignal *signal2 = [RACSignal error:error];
RACSignal *signal3 = [RACSignal empty];
RACSignal *signal4 = [RACSignal never];

动态信号

源码解析:创建一个RACDynamicSignal并且保存一个didSubscribeblock,返回RACSignal对象。
注意:在创建动态信号结束的时候要sendCompleted

1
2
3
4
5
6
7
8
9
RACSignal *signal5 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
NSError *error;
[subscriber sendError:error];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
}];
}];

cocoa桥接

1
2
3
4
5
UIButton *view;
RACSignal *signal6 = [view rac_signalForSelector:@selector(setFrame:)];
RACSignal *signal7 = [view rac_willDeallocSignal];
RACSignal *signal8 = [view rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *signal9 = RACObserve(view, backgroundColor);

信号变换

1
2
3
RACSignal *signal10 = [signal1 map:^id _Nullable(id  _Nullable value) {
return [value substringFromIndex:1];
}];

序列转换

1
2
RACSequence *squence = [RACSequence empty];
RACSignal *signal11 = squence.signal;

信号的使用

订阅一个信号

源码大致顺序就是创建subscriber,调用subscriber,block回调

1
2
3
4
5
6
7
[signal10 subscribeNext:^(id  _Nullable x) {
NSLog(@"next value is %@",x);
} error:^(NSError * _Nullable error) {
NSLog(@"some error:%@",error);
} completed:^{
NSLog(@"finished success");
}];

绑定(常用,kvo)

1
RAC(view,backgroundColor) = signal10;

cocoa桥接

1
2
3
4
//当响应signal1/signal2的时候出发converPoint:toView:
[view rac_liftSelector:@selector(convertPoint:toView:) withSignals:signal1,signal2, nil];
[view rac_liftSelector:@selector(convertPoint:toView:) withSignalsFromArray:@[signal3,signal4]];
[view rac_liftSelector:@selector(convertPoint:toView:) withSignalOfArguments:signal5];

订阅过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"dispose");
}];
}];
RACDisposable *disposable = [signal subscribeNext:^(id _Nullable x) {
NSLog(@"next value is %@",x);
} error:^(NSError * _Nullable error) {
NSLog(@"some error:%@",error);
} completed:^{
NSLog(@"finished success");
}];
[disposable dispose];

RACSignal各种操作

对值操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
RACSignal *signala = [RACSignal return:@1];
RACSignal *signalb = [signala map:^id _Nullable(NSNumber *value) {
return @(value.intValue * 2);
}];
//替换为信号为8的信号
RACSignal *signalc = [signala mapReplace:@8];

//将tuple加和
RACSignal *signald = [signala reduceEach:^id (NSNumber *a,NSNumber *b){
return @(a.intValue + b.intValue);
}];
[signala subscribeNext:^(id _Nullable x) {
NSLog(@"next %@",x);
} completed:^{
NSLog(@"compltet");
}];

数量操作

1
2
3
4
5
6
7
8
9
RACSignal *signale = [signala filter:^BOOL(NSString *value) {
return value.length > 2;
}];
RACSignal *signalf = [signala take:2];
RACSignal *signalg = [signala skip:1];
RACSignal *signalh = [signala startWith:@7];
RACSignal *signali = [signala repeat];
RACSignal *signalj = [signala retry];
RACSignal *signalk = [signala retry:3];

副作用

1
2
3
[signala doNext:^(id  _Nullable x) {

}];

收集

1
[signala collect];

折叠、汇聚

1
2
3
4
5
6
7
8
//aggregate 信号结束前一直加和,不回调
[signala aggregateWithStart:@1 reduce:^id _Nonnull(NSNumber * running, NSNumber *next) {
return @(running.intValue + next.intValue);
}];
//scan 有新信号来的时候会调起加和 回调
[signala scanWithStart:@1 reduce:^id _Nullable(NSNumber * running,NSNumber * next) {
return @(running.intValue + next.intValue);
}];

实践操作 timer信号

1
2
3
RACSignal *signall = [signala delay:1];
//throttle 用户快速点击,防止多次请求
[signala throttle:2];

多个信号组合操作

首尾合并,第一个信号终止后拼接第二个信号

1
2
3
RACSignal *signala = [RACSignal return:@2];
RACSignal *signalb = [RACSignal return:@5];
RACSignal *signalc = [signala concat:signalb];

根据时间轴合并,如果不是同一线程,signal会跳

1
2
[signalb merge:signala];
`

zip 拉链 连个信号打包成tuple的形式,场景:需要a请求数据和b请求数据,此时zip两个数据的信号

1
[signalb zipWith:signala];

combinelatest 两个信号互相与最新的信号组合成tuple

1
[signalb combineLatestWith:signala];

sample采样 当signala收到信号的时候会在新的信号中取signalb中的信号

1
[signalb sample:signala];

takeUntil 当signalb信号相应时signala截止

1
[signala take:signalb];

akeuntilreplacement 当signalb信号相应时signala截止,并且在接下来接入signalb的信号

1
[signalb takeUntilReplacement:signala];

CATALOG
  1. 1. RACSignal使用基础
    1. 1.1. 获取信号的方式
      1. 1.1.1. 单元信号
      2. 1.1.2. 动态信号
      3. 1.1.3. cocoa桥接
      4. 1.1.4. 信号变换
      5. 1.1.5. 序列转换
    2. 1.2. 信号的使用
      1. 1.2.1. 订阅一个信号
      2. 1.2.2. 绑定(常用,kvo)
      3. 1.2.3. cocoa桥接
    3. 1.3. 订阅过程
    4. 1.4. RACSignal各种操作
      1. 1.4.1. 对值操作
      2. 1.4.2. 数量操作
      3. 1.4.3. 副作用
      4. 1.4.4. 收集
      5. 1.4.5. 折叠、汇聚
      6. 1.4.6. 实践操作 timer信号
      7. 1.4.7. 多个信号组合操作