• 组合:
concat组合:
          按一定顺序执行皇上与皇太子关系
concat底层实现:
    1.当拼接信号被订阅,就会调用拼接信号的didSubscribe
    2.didSubscribe中会先订阅第一个源信号(signalA)
    3.会执行第一个源信号(signalA)的didSubscribe
    4.第一个源信号(signalA)didSubscribe中发送值,就会调用第一个源信号(signalA)订阅者的nextBlock,通过拼接信号的订阅者把值发送出来.
    5.第一个源信号(signalA)didSubscribe中发送完成,就会调用第一个源信号(signalA)订阅者的completedBlock,订阅第二个源信号(signalB)这时候才激活(signalB)。
    6.订阅第二个源信号(signalB),执行第二个源信号(signalB)的didSubscribe
    7.第二个源信号(signalA)didSubscribe中发送值,就会通过拼接信号的订阅者把值发送出来.
- (void)concat
{
//创建信号A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送请求
NSLog(@"发送上部分的请求");
//发送信号
[subscriber sendNext:@"上部分数据"];
//发送完毕
//加上后就可以上部分发送完毕后发送下半部分信号
[subscriber sendCompleted];
return nil;
}]; //创建信号B
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送请求
NSLog(@"发送下部分的请求");
//发送信号
[subscriber sendNext:@"下部分数据"];
return nil;
}];
//创建组合信号
//concat:按顺序去连接(组合)
//注意:第一个信号必须调用sendCompleted
RACSignal *concat = [signalA concat:signalB];
//订阅组合信号
[concat subscribeNext:^(id x) {
//既能拿到A信号的值,又能拿到B信号的值
NSLog(@"%@", x);
}];
}
 
then:
     用于连接两个信号,当第一个信号完成,才会连接then返回的信号
     注意: 使用then之前的信号的值会被忽略掉.
底层实现:
    1、先过滤掉之前的信号发出的值。
    2.使用concat连接then返回的信号
- (void)then
{
//创建信号A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送请求
NSLog(@"发送上部分的请求");
//发送信号
[subscriber sendNext:@"上部分数据"];
//发送完毕
//加上后就可以上部分发送完毕后发送下半部分信号
[subscriber sendCompleted];
return nil; }]; //创建信号B
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送请求
NSLog(@"发送下部分的请求");
//发送信号
[subscriber sendNext:@"下部分数据"];
return nil; }]; //thenSignal组合信号
//then:会忽略掉第一个信号的所有值
RACSignal *thenSignal = [signalA then:^RACSignal *{
//返回的信号就是需要组合的信号
return signalB;
}];
//订阅信号
[thenSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}]; /*
结果:
发送上部分的请求
发送下部分的请求
下部分数据
*/
}
 
merge
     把多个信号合并为一个信号,任何一个信号有新值的时候就会调用,没有顺序
- (void)merge
{
//创建信号A
RACSubject *signalA = [RACSubject subject];
//创建信号B
RACSubject *signalB = [RACSubject subject]; //组合信号
RACSignal *mergeSignal = [signalA merge:signalB]; //订阅信号
[mergeSignal subscribeNext:^(id x) {
//任意一个信号发送内容都会来到这个block
NSLog(@"%@", x);
}]; //发送数据
[signalB sendNext:@"下部分"];
[signalA sendNext:@"上部分"];
/*结果:下部分上部分*/
}
 
zipWith: 等所有信号都发送内容的时候才会调用(夫妻关系)
     把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件
底层实现:
    1.定义压缩信号,内部就会自动订阅signalA,signalB
    2.每当signalA或者signalB发出信号,就会判断signalA,signalB有没有发出个信号,有就会把最近发出的信号都包装成元组发出。
- (void)zipWith
{
//创建信号A
RACSubject *signalA = [RACSubject subject];
//创建信号B
RACSubject *signalB = [RACSubject subject];
//压缩成一个信号
//当一个界面多个请求时,要等所有的请求都完成才能更新UI
//打印顺序跟组合顺序有关,跟发送顺序无关
RACSignal *zipSignal = [signalA zipWith:signalB];
//订阅信号
[zipSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
//发送信号
[signalA sendNext:@"HMJ"];
[signalB sendNext:@"GQ"];
/*
结果
<RACTuple: 0x7ffd8351f120>
(
HMJ,
GQ
)
*/
}
 
combineLatest:
     将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。
底层实现:
    1.当组合信号被订阅,内部会自动订阅signalA,signalB,必须两个信号都发出内容,才会被触发。
    2.并且把两个信号组合成元组发出。
- (void)combineLatest
{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"A"];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"B"];
return nil;
}];
//把两个信号组合成一个信号
RACSignal *combineSignal = [signalA combineLatestWith:signalB];
//订阅组合信号
[combineSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
}
reduce聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值
     常见的用法(先组合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
reduce中的block简介:
    reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
    reduceblcok的返回值:聚合信号之后的内容。
底层实现:
    订阅聚合信号,每次有内容发出,就会执行reduceblcok,把信号内容转换成reduceblcok返回的值。
- (void)combineLatestWithReduce
{
/*登录界面:两个文本框(账户,密码) + 一个登录按钮*/ //组合多个信号
//reduce:聚合
//reduceBlock的参数与组合的信号一一对应,可以在reduce:后拿到信号的值
RACSignal *combineSignal = [RACSignal combineLatest:@[_accountName.rac_textSignal, _passWord.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){
//block:只要源信号发送内容就会调用,组合成新的一个值
//聚合的值就是组合信号的内容
return @(account.length && pwd.length);
}];
//订阅信号
// [combineSignal subscribeNext:^(id x) {
// self.loginBtn.enabled = [x boolValue];
//
// }];
//等同于
RAC(self.loginBtn, enabled) = combineSignal;
}

RAC中常见的高级用法-组合的更多相关文章

  1. RAC中常见的高级用法-bind方法

    RAC操作思想:      Hook(钩子)思想 RAC核心方法:bind      bind方法      假设想监听文本框的内容,并且在每次输出结果的时候,都在文本框的内容拼接一段文字" ...

  2. RAC中常见的高级用法-过滤

    filter      过滤信号,使用它可以获取满足条件的信号. - (void)filter { //只有当我们文本框内容长度大于5才想要获取文本框的内容 [[_passWord.rac_textS ...

  3. 详解Vue中watch的高级用法

    我们通过实例代码给大家分享了Vue中watch的高级用法,对此知识点有需要的朋友可以跟着学习下. 假设有如下代码: <div> <p>FullName: {{fullName} ...

  4. linux中find命令高级用法

    前言 在<Linux中的文件查找技巧>一文中,我们已经知道了文件查找的基本方法,今天我们介绍find命令的一些高级使用技巧.它能满足我们一些更加复杂的需求. 查找空文件或空目录 有时候需要 ...

  5. pymongo常见的高级用法

    pymongo是python中基于mongodb数据库开发出来的,比mongoengine要高级一些,也要好用一些. 基本的增删查改就不说了 insert() delete() find() upda ...

  6. SQL语句中的select高级用法

    #转载请联系 为了更好的了解下面的知识点,我们先创建两张表并插入数据. # 学生表 +----+-----------+------+--------+--------+--------+------ ...

  7. Flutter 中渐变的高级用法

    Flutter 中渐变有三种: LinearGradient:线性渐变 RadialGradient:放射状渐变 SweepGradient:扇形渐变 看下原图,下面的渐变都是在此图基础上完成. Li ...

  8. 随机记录工作中常见的sql用法错误(一)

    没事开始写博客,留下以前工作中常用的笔记,内容不全或者需要补充的可以留言,我只写我常用的. 网上很多类似动软生成器的小工具,这类工具虽然在表关系复杂的时候没什么软用,但是在一些简单的表结构关系还是很方 ...

  9. Sql server存储过程中常见游标循环用法

    用游标,和WHILE可以遍历您的查询中的每一条记录并将要求的字段传给变量进行相应的处理 DECLARE ), ), @A3 INT DECLARE YOUCURNAME CURSOR FOR SELE ...

随机推荐

  1. Linux&C open creat read write lseek 函数用法总结

    一:五个函数的参数以及返回值. 函数                                 参数                      返回值     open (文件名,打开方式以及读 ...

  2. 【Python+postman接口自动化测试】(7)Postman 的使用教程

    Postman v6的使用 Postman: 简单方便的接口调试工具,便于分享和协作.具有接口调试,接口集管理,环境配置,参数化,断言,批量执行,录制接口,Mock Server, 接口文档,接口监控 ...

  3. flask cache

    http://brunorocha.org/python/flask/using-flask-cache.html 如何在大项目中使用cache 新建全局cache.py cache = Cache( ...

  4. .Net Core微服务——Ocelot(3):超时、熔断、限流

    基本概念 超时.熔断.限流听起来好像很远,但实际上用在方方面面.很多人可能还搞不懂熔断是做什么,其实可以把熔断理解为一种防护措施.做个假设,在微服务体系下,某个下游服务响应很慢,然后随着时间推移,会有 ...

  5. 体验.NET Core使用IKVM对接Java

    前言 与第三方对接最麻烦的是语言不同,因语言不同内置实现相关标准加密算法还是略微有所差异,对接单点登录场景再寻常不过,由于时间紧迫且对接方使用Java,所以留给我对接开发和联调的时间本就不多,于是乎, ...

  6. 5.0jemter(英文版)录制脚本,进行压力测试

    压力测试的目的:找到瓶颈.优化速率 1.jemter,Test Plan-->>Add-->>Threds(users)-->>Thred Group创建线程组 2 ...

  7. react之redux状态管理

    1.传统MVC框架的缺陷 模型(model)-视图(view)-控制器(controller)的缩写 V即View视图:用户看到并与之交互的界面. M即Model模型是管理数据:很多业务逻辑都在模型中 ...

  8. [luogu3781]切树游戏

    考虑暴力的dp,即用$f_{i,j}$表示以$i$为根的子树内,强制$i$必须选且异或为$j$的方案数,转移用FWT即可,求出该dp数组的时间复杂度为$o(nm\log_{2}m)$ 由于是全局的方案 ...

  9. tomcat去除项目访问路径限制

    首先打开tomcat的\apache-tomcat-7.0.73\confserver.xml文件 在 </ <Host name="localhost" appBas ...

  10. python并行计算之mpi4py的安装与基本使用

    技术背景 在之前的博客中我们介绍过concurrent等python多进程任务的方案,而之所以我们又在考虑MPI等方案来实现python并行计算的原因,其实是将python的计算任务与并行计算的任务调 ...