美文网首页
RAC常用方法replay、replayLast、replayL

RAC常用方法replay、replayLast、replayL

作者: 大齿一鲸 | 来源:发表于2018-06-13 10:02 被阅读88次

ReactCocoa 版本号:V2.5
Language: ObjectC
XCode 版本号: V9.4
Note: 阅读本文章假设您已经有了一定的ReactCocoa基础知识

一、RACSingal (信号)
1.每次订阅信号,都会导致信号的订阅代码被调用,且参数subscriber的值每次都不一样。
2.订阅者只能收到订阅后发送的所有消息,无法收到之前发送的历史消息。

RACSignal *sig = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"我被订阅了,%@", subscriber); //每次有人订阅都会执行这段Block, subscriber每次值不一样
 
    [subscriber sendNext:@"aaa"];  //发送消息:aaa
    return nil;
}];

NSLog(@"11马上订阅信号"); //第一步打印
[sig subscribeNext:^(id x) { //一旦被订阅上面的订阅代码被执行
    NSLog(@"11接收到:%@",x); //上面的订阅代码里发送了消息aaa,这里能收到
}];

NSLog(@"22马上订阅信号");
[sig subscribeNext:^(id x) { //又被订阅一次,导致上面的订阅代码再次执行
    NSLog(@"222接收到:%@",x);  //上面订阅代码里发送了消息aaa,这里能收到,上面的订阅者11也能收到
}];

对比一下控制台打印结果如下图:


1.png

把上面代码进行简单修改一下

__block id<RACSubscriber> s = nil;
RACSignal *sig = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"我被订阅了,%@", subscriber); //每次有人订阅都会执行这段Block, subscriber每次值不一样
    s =  subscriber; //保存到外部变量,让Block外面去发送消息
    return nil;
}];

NSLog(@"马上发消息aaa");
[s  sendNext:@"aaa"];  //sig信号此时还没有被订阅,上面的订阅代码没有执行,s此时值为nil,发送失败

NSLog(@"11马上订阅信号"); 
[sig subscribeNext:^(id x) { //一旦被订阅上面的订阅代码被执行,s变量不为空
    NSLog(@"11接收到:%@",x); //由于上面的订阅代码里并没有发送消息,所以这里收不到任何消息
}];

NSLog(@"马上发消息bbb");
[s  sendNext:@"bbb"];  //sig信号上面已经被订阅了,且s保存了上一次值,发送成功,上面订阅者11能收到消息

NSLog(@"22马上订阅信号");
[sig subscribeNext:^(id x) { //又被订阅一次,导致上面的订阅代码再次执行,s变量变成新的值
    NSLog(@"222接收到:%@",x);  //由于s变量更新后并没有发送消息,所以这里也接收不到消息
}];

NSLog(@"马上发消息ccc");
[s  sendNext:@"ccc"];  //注意,s变量是最后一次订阅后的值,所以此次发送的消息,只有最后一个订阅者能接收到

代码执行结果如下:

44.png

二、replay :
1.调用replay,会导致源信号的订阅代码先被调用
2.信号多次被订阅不会重复执行源信号的订阅代码
3.订阅者能收到所有历史已经发送的、未来发送的所有消息。

__block id<RACSubscriber> s = nil;
RACSignal *sig = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"开始发送");     //1.第一步执行。replay内部会先订阅此信号导致此Block会被调用
    s = subscriber;       //将发送者保存到外部变量,因为block外部需要发送信号
    [s sendNext:@"aaa"];  //注意,此时此刻信号还没有订阅者
    return nil;
}] replay];

NSLog(@"马上发送消息bbb");//2.第二步打印 
[s sendNext:@"bbb"];  //此时此刻,信号还是没有订阅者

[sig subscribeNext:^(id x) {//订阅不会导致信号的订阅代码被调用
    NSLog(@"11接收到:%@",x); //3.第三步执行,神奇的事情发生了,这里依然能接收到前面已经发送出去的消息aaa、bbb
}];

[s sendNext:@"ccc"]; //继续发送,会导致前面的订阅者收到消息:ccc
[s sendNext:@"ddd"]; //继续发送,会导致前面的订阅者收到消息:ddd
[s sendNext:@"eeee"];//继续发送,会导致前面的订阅者收到消息:eeee

[sig subscribeNext:^(id x) {
    NSLog(@"222接收到:%@",x);  //前面已经发送出去的消息都能收到:aaa、bbb、ccc、ddd、eeee
}];

对比一下控制台打印结果如下图:

---.png

三、replayLast :
1.调用replayLast,会导致源信号的订阅代码先被调用(与replay相同)
2.信号多次被订阅不会重复执行源信号的订阅代码(与replay相同)
3.订阅者只能收到历史已经发送的最近一条信息、未来发送的所有消息。(与replay唯一不同)

__block id<RACSubscriber> s = nil;
RACSignal *sig = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"开始发送");     //1.第一步执行。replayLast内部会先订阅此信号导致此Block会被调用
    s = subscriber;       //将发送者保存到外部变量,因为block外部需要发送信号
    [s sendNext:@"aaa"];  //注意,此时此刻信号还没有订阅者
    return nil;
}] replayLast];

[s sendNext:@"bbb"];  //此时此刻,信号还是没有订阅者

[sig subscribeNext:^(id x) {
    NSLog(@"11接收到:%@",x); //2.第二部执行,这里只能收到前面历史消息中最近的一条:bbb,无法收到aaa消息。
}];

[s sendNext:@"ccc"]; //继续发送,会导致前面的订阅者收到消息:ccc
[s sendNext:@"ddd"]; //继续发送,会导致前面的订阅者收到消息:ddd
[s sendNext:@"eeee"];//继续发送,会导致前面的订阅者收到消息:eeee

[sig subscribeNext:^(id x) {//再次订阅不会导致订阅代码再次执行
    NSLog(@"222接收到:%@",x);  //只能收到前面的最近一条消息:eeee
}];

[s sendNext:@"ffff"];//继续发送,会导致前面的两个订阅者都收到消息:ffff

控制台打印结果如下图:


0.png

四、replayLazily :
1.调用replayLazily,会导致源信号的订阅代码只在信号首次被订阅时调用(与replay唯一不同)
2.信号多次被订阅不会重复执行源信号的订阅代码(与replay相同)
3.订阅者能收到所有历史已经发送的、未来发送的所有消息。(与replay相同)

__block id<RACSubscriber> s = nil;
RACSignal *sig = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"开始发送");     //首次订阅此信号导致此Block会被调用一次,此后不会调用
    s = subscriber;       //将发送者保存到外部变量,因为block外部需要发送信号
    [s sendNext:@"aaa"];
    return nil;
}] replayLazily];

NSLog(@"马上发送消息bbb");//1.第一步打印
[s sendNext:@"bbb"];  //此时此刻发送失败,因为上面Block未执行,s值是nil

NSLog(@"11马上订阅消息");//2.第二步打印
[sig subscribeNext:^(id x) {//首次订阅,上面的Block被执行
    NSLog(@"11接收到:%@",x); //Block里发送了消息,此处收到消息:aaa
}];

[s sendNext:@"ccc"]; //继续发送,会导致前面的订阅者收到消息:ccc
[s sendNext:@"ddd"]; //继续发送,会导致前面的订阅者收到消息:ddd
[s sendNext:@"eeee"];//继续发送,会导致前面的订阅者收到消息:eeee

[sig subscribeNext:^(id x) {//再次订阅不会导致订阅代码再次执行
    NSLog(@"222接收到:%@",x);  //前面发送的消息全部能收到:aaa、ccc、ddd、eeee
}];

[s sendNext:@"ffff"];//继续发送,会导致前面的两个订阅者都收到消息:ffff

控制台打印结果如下图:

4.png

相关文章

  • RAC常用方法replay、replayLast、replayL

    ReactCocoa 版本号:V2.5Language: ObjectCXCode 版本号: V9.4Note: ...

  • 菜鸟运用RAC对replay,replayLast,replay

    前言 在上一篇文章中菜鸟开始学习ReactiveObjc运用的记录(二)自己已经对RAC的一些基本概念有了一点了解...

  • RAC(二)

    RAC常用方法 (instancetype)flattenMap:(RACStream * (^)(id valu...

  • ReactiveObjC 源码阅读笔记 (-rac_signal

    常用方法响应 -rac_signalForSelector: 使用: 源码 NSObject+RACSelecto...

  • RAC常用方法

    前言 由于时间的问题,暂且只更新这么多了,后续还会持续更新本文《最快让你上手ReactiveCocoa之进阶篇》,...

  • RAC整理

    RAC常用的方法,搭配@weakify(self); @weakify(self); 通知 control Ges...

  • RAC(iOS)常用方法

    前言 在学完RAC后发现方法的用法总是会忘,于是简单记录一下在工程中的用法。 RAC常用方法 UIButton点击...

  • RAC之四(RAC常用方法)

    1.代替代理 2.监听事件 3.代替通知 4.监听文本框改变 5.代替KVO 总结:使用RAC这些方法,可以让我们...

  • RAC常用绑定方法

    // 绑定事件

  • RAC常用方法汇总

    一、iOS内部对不同事件的处理 iOS中对不同事件作出响应时,会用不同的方式来处理这些业务逻辑。比如按钮的点击使用...

网友评论

      本文标题:RAC常用方法replay、replayLast、replayL

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