RACSubject
冷热信号概念
信号源分为热信号和冷信号两种,热信号是不管有没有订阅者都会发消息,而冷信号只有在订阅都订阅时才会发送消息。通俗来讲,热信号就像直播,不管有没有观众都会一直播,当观众看时,也只能看这个时间之后的内容,这个点之前的看不到,而冷信息就相当于点播,每次有订阅者时,视频内容都会从头到尾的播一遍 参考。
举栗子:
RACSubject *subject = [RACSubject subject];
// Subscriber 1
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"1st Sub: %@", x);
}];
[subject sendNext:@1];
// Subscriber 2
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"2nd Sub: %@", x);
}];
[subject sendNext:@2];
// Subscriber 3
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"3rd Sub: %@", x);
}];
[subject sendNext:@3];
[subject sendCompleted];
结果:
2019-10-30 10:15:09.190910+0800 RACTest[22045:1676452] 1st Sub: 1
2019-10-30 10:15:09.191331+0800 RACTest[22045:1676452] 1st Sub: 2
2019-10-30 10:15:09.191606+0800 RACTest[22045:1676452] 2nd Sub: 2
2019-10-30 10:15:09.191764+0800 RACTest[22045:1676452] 1st Sub: 3
2019-10-30 10:15:09.191970+0800 RACTest[22045:1676452] 2nd Sub: 3
2019-10-30 10:15:09.192099+0800 RACTest[22045:1676452] 3rd Sub: 3
RACSignal bind的理解
bind方法的实现:
- (RACSignal *)bind:(RACStreamBindBlock (^)(void))block {
return [RACSignal createSignal:^RACDisposable *(id subscriber) { //(1)
RACStreamBindBlock bindBlock = block(); //(2)
[self subscribeNext:^(id x) { //(3)
BOOL stop = NO;
RACSignal *signal = (RACSignal *)bindBlock(x, &stop); //(4)
if (signal !=nil) {
[signal subscribeNext:^(id x) { //(5)
[subscriber sendNext:x]; //(6)
} error:^(NSError *error) {
[subscriber sendError:error]; //(10)
} completed:^{
[subscriber sendCompleted]; //(9)
}];
}
if (signal == nil || stop) {
[subscriber sendCompleted]; //(9)
}
} error:^(NSError *error) {
[subscriber sendError:error]; //(10)
} completed:^{
[subscriber sendCompleted]; //(9)
}];
return nil;
}];
}
- 假设原信号为A,bind方法是创建一个新的信号B
- B信号调用subscribeNext时,会执行block(1),block(1)执行时,会去订阅信号A,在信号A发出变化时,调用block(3),block(3)会根据bind返回的block生成一个新的信号C,并且订阅信号C,信号C收到变化消息时,会通知B的订阅都,此时就触发了B的订阅回调。
RACSignal *signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"发送信号signalA");
[subscriber sendNext:@"我是signalA"];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"清理信号signalA");
}];
}];
RACSignal *signalB = [signalA bind:^RACSignalBindBlock _Nonnull{
return ^(id value, BOOL *stop){
NSString *newString = [NSString stringWithFormat:@"%@经过变更",value];
NSLog(@"内容更改%@",newString);
return [RACSignal return:newString];
};
}];
NSLog(@"订阅信号signalB");
[signalB subscribeNext:^(id _Nullable x) {
NSLog(@"信号signalB收到通知:%@",x);
}];
打印结果:
2019-10-30 10:03:35.450362+0800 RACTest[21997:1672464] 订阅信号signalB
2019-10-30 10:03:35.453114+0800 RACTest[21997:1672464] 发送信号signalA
2019-10-30 10:03:35.453235+0800 RACTest[21997:1672464] 内容更改我是signalA经过变更
2019-10-30 10:03:35.453652+0800 RACTest[21997:1672464] 信号signalB收到通知:我是signalA经过变更
2019-10-30 10:03:35.454191+0800 RACTest[21997:1672464] 清理信号signalA
zip合并信号
我说下个人猜的实现方式,如果有不对的地方,还请看官指正,以免误人子弟。
zip会给每个信号分配一个类似队列的存储空间(FIFO),信号调sendNext时,就往其队列里存储这个值,每次存储前,都会检查下,是不是zip的几个信号都有值了,如果是则回调,会删除输出过的值,否则不回调,当有一个信号发送sendCompleted时,等此信号队列的值都输出完后,zip执行complete。
请吃栗子:
RACSubject *A = [RACSubject subject];
RACSubject *B = [RACSubject subject];
RACSubject *C = [RACSubject subject];
RACSignal *zip = [RACSignal zip:@[A,B,C] reduce:^id(NSString *a,NSString *b,NSString *c){
return [NSString stringWithFormat:@"%@%@%@",a,b,c];
}];
[zip subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
[A sendNext:@"A1"];
[A sendNext:@"A2"];
[B sendNext:@"B1"];
[C sendNext:@"C1"];
[C sendNext:@"C2"];
[A sendNext:@"A3"];
[B sendNext:@"B2"];
[B sendNext:@"B3"];
[C sendNext:@"C3"];
结果:
2019-10-30 10:17:22.584257+0800 RACTest[22056:1677335] A1B1C1
2019-10-30 10:17:22.584706+0800 RACTest[22056:1677335] A2B2C2
2019-10-30 10:17:22.585092+0800 RACTest[22056:1677335] A3B3C3
combineLatestWith合并信号
理解:
1、存储每个信号的value,等所有合并的信号都发送过sendNext时,才输出
2、如果在输出前,某个信号调sendNext两次以上,则会用最新的值覆盖旧值。
3、输出后,信号的值不会被清除
请吃票子:
RACSubject *A = [RACSubject subject];
RACSubject *B = [RACSubject subject];
RACSubject *C = [RACSubject subject];
RACSignal *combined = [RACSignal combineLatest:@[A,B,C] reduce:^id(NSString *a,NSString *b,NSString *c){
return [NSString stringWithFormat:@"%@%@%@",a,b,c];
}];
[combined subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
[A sendNext:@"A1"];
[A sendNext:@"A2"];
[B sendNext:@"B1"];
[C sendNext:@"C1"];
[C sendNext:@"C2"];
[A sendNext:@"A3"];
[A sendNext:@"A4"];
[B sendNext:@"B2"];
结果:
2019-10-30 10:36:05.440970+0800 RACTest[22127:1682750] A2B1C1
2019-10-30 10:36:05.441308+0800 RACTest[22127:1682750] A2B1C2
2019-10-30 10:36:05.441660+0800 RACTest[22127:1682750] A3B1C2
2019-10-30 10:36:05.442017+0800 RACTest[22127:1682750] A4B1C2
2019-10-30 10:36:05.442218+0800 RACTest[22127:1682750] A4B2C2
concat
理解:
1、串行执行
2、只有等上一个信号执行sendCompleted时才会响应下一个信号的sendNext(只是不响应,但不会阻塞线程往下走哦)
请吃票子:
RACSubject *A = [RACSubject subject];
RACSubject *B = [RACSubject subject];
RACSubject *C = [RACSubject subject];
RACSignal *concat = [[A concat:B]concat:C];
[concat subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
[A sendNext:@"A1"];
[A sendNext:@"A2"];
[A sendCompleted];
[B sendNext:@"B1"];
[C sendNext:@"C1"];
[C sendNext:@"C2"];
[A sendNext:@"A3"];
[A sendNext:@"A4"];
[B sendNext:@"B2"];
结果:
2019-10-30 10:41:35.082761+0800 RACTest[22150:1684987] A1
2019-10-30 10:41:35.082870+0800 RACTest[22150:1684987] A2
2019-10-30 10:41:35.083049+0800 RACTest[22150:1684987] B1
2019-10-30 10:41:35.083093+0800 RACTest[22150:1684987] B2
merge
1、只要有信号调sendNext都会响应。
2、某个信号 发送sendCompleted只停止当前的信号。
3、所有的信号sendCompleted时,merge才complete。
请吃栗子
RACSubject *A = [RACSubject subject];
RACSubject *B = [RACSubject subject];
RACSubject *C = [RACSubject subject];
RACSignal *merge = [RACSignal merge:@[A,B,C]];
[merge subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
} completed:^{
NSLog(@"merge完成");
}];
[A sendNext:@"A1"];
[A sendNext:@"A2"];
[A sendCompleted];
[B sendNext:@"B1"];
[C sendNext:@"C1"];
[C sendNext:@"C2"];
[A sendNext:@"A3"];
[B sendNext:@"B2"];
[B sendNext:@"B3"];
[B sendCompleted];
[C sendCompleted];
结果
2019-10-30 11:49:22.343006+0800 RACTest[22417:1706356] A1
2019-10-30 11:49:22.343117+0800 RACTest[22417:1706356] A2
2019-10-30 11:49:22.343243+0800 RACTest[22417:1706356] B1
2019-10-30 11:49:22.343291+0800 RACTest[22417:1706356] C1
2019-10-30 11:49:22.343324+0800 RACTest[22417:1706356] C2
2019-10-30 11:49:22.343357+0800 RACTest[22417:1706356] B2
2019-10-30 11:49:22.343562+0800 RACTest[22417:1706356] B3
2019-10-30 11:49:22.343676+0800 RACTest[22417:1706356] merge完成
网友评论