• 组合:
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. Centos7下安装BlockScout

    简介 BlockScout是一个Elixir应用程序,允许用户搜索以太坊网络(包括所有叉子和侧链)上的交易,查看账户和余额以及验证智能合约.BlockScout为用户提供了一个全面,易于使用的界面,以 ...

  2. APP 自动化之系统按键事件(五)

    转载记录方便后续自己使用: 代码就一句driver.keyevent()括号内填入的是物理按键的数字代号 代号表: 电话键 KEYCODE_CALL 拨号键 5 KEYCODE_ENDCALL 挂机键 ...

  3. win10 vscode安装babel

    第一步:安装 babel-cli cd进入项目根目录,执行命令: npm install --global babel-cli 第二步:检测第一步是否成功,输入命令 babel --version,若 ...

  4. Java使用iText7生成PDF

    前言 我们之前使用js库html2canvas + jspdf实现html转PDF.图片,并下载(详情请戳:html页面转PDF.图片操作记录),大致原理是将页面塞到画布里,以图片的方式放到PDF中, ...

  5. Effective C++ 总结笔记(三)

    三.资源管理 13.以对象管理资源 1.为了防止资源泄漏,请使用RAII对象,在构造函数里面获得资源,并在析构函数里面释放资源. 2. 引用计数型智慧指针(RCSP):持续追踪多少个指针指向该资源,无 ...

  6. Django笔记&教程 3-1 模板(Template)基础

    Django 自学笔记兼学习教程第3章第1节--模板(Template)基础 点击查看教程总目录 1 介绍 模板文件:让Django能够自动生成html代码 作为一个web框架,Django需要需要在 ...

  7. GO语言数据结构之链表

    链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括两个部分: ...

  8. [spojDIVCNT1]Counting Divisors

    定义 约定1:以下分数都是最简,且令$\frac{1}{0}$有意义,其大于其余分数,并称平行于$y$轴的直线斜率为$-\frac{1}{0}$ 分数加:对于分数$a=\frac{a_{1}}{a_{ ...

  9. vue的常用指令

    https://www.bootcdn.cn/ 前端资源库 <!-- 常用内置指令 v:text : 更新元素的 textContent v-html : 更新元素的 innerHTML v-i ...

  10. 十一. Go并发编程--singleflight

    一.前言 1.1 为什么需要Singleflight? 很多程序员可能还是第一次听说,本人第一次听说这个的时候以为翻译过来就是程序设计中被称为的是 "单例模式". google之后 ...